MySQL: функции XML
Функции XML
Функции ExtractValue () (извлекает значение из строки XML.) И UpdateXML () (возвращает замененный фрагмент XML) предоставляют базовые возможности XPath 1.0. Выражения XPath использовали эти функции для поддержки пользовательских переменных и локальных хранимых переменных программы.
Функция ExtractValue ()
Функция ExtractValue () используется для извлечения значения из строки XML с использованием нотации XPath.
Синтаксис:
EXTRACTVALUE ()
Пользовательские переменные: переменные, использующие синтаксис [электронная почта защищена] _name (пользовательские переменные), не проверяются. Вы не получите никаких предупреждений или ошибок от сервера, если переменная имеет неправильный тип или ей ранее не было присвоено значение.
mysql> SET @xml = '<a> <b> X </ b> <b> Y </ b> <b> Z </ b> </a>'; Запрос в порядке, затронуто 0 строк (0,00 с) mysql> SET @i = 1, @j = 2, @k = 0; Запрос в порядке, затронуто 0 строк (0,00 с) mysql> SELECT @i, ExtractValue (@xml, '// b [ [электронная почта защищена] ]'); + ------ + ------------------------------- + | @i | ExtractValue (@xml, '// b [ [электронная почта защищена] ]') | + ------ + ------------------------------- + | 1 | X | + ------ + ------------------------------- + 1 ряд в наборе (0,02 сек) mysql> SELECT @j, ExtractValue (@xml, '// b [ [электронная почта защищена] ]'); + ------ + ------------------------------- + | @j | ExtractValue (@xml, '// b [ [электронная почта защищена] ]') | + ------ + ------------------------------- + | 2 | Y | + ------ + ------------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT @k, ExtractValue (@xml, '// b [ [email protected] ]'); + ------ + ------------------------------- + | @k | ExtractValue (@xml, '// b [ [электронная почта защищена] ]') | + ------ + ------------------------------- + | 0 | | + ------ + ------------------------------- + 1 ряд в наборе (0,00 сек)
Переменные в хранимых программах: Переменные, использующие синтаксис $ variable_name, могут быть объявлены и использованы с этими функциями, когда они вызываются внутри хранимых программ. Такие переменные являются локальными для хранимой программы, в которой они определены, и строго проверяются на тип и значение.
mysql> РАЗДЕЛИТЕЛЬ | mysql> ИСПЫТАНИЕ База данных изменена mysql> CREATE PROCEDURE myproc () -> НАЧАТЬ -> ОБЪЯВИТЬ i INT DEFAULT 1; -> ОБЪЯВИТЬ xml VARCHAR (25) ПО УМОЛЧАНИЮ '<a> M </a> <a> N </a> <a> O </a>'; -> -> Пока я <5 DO -> ВЫБРАТЬ xml, i, ExtractValue (xml, '// a [$ i]'); -> SET i = i + 1; -> END WHILE; -> КОНЕЦ | Запрос в порядке, затронуто 0 строк (0,03 сек) mysql> DELIMITER; mysql> CALL myproc (); + -------------------------- + ------ + --------------- --------------- + | XML | я | ExtractValue (xml, '// a [$ i]') | + -------------------------- + ------ + --------------- --------------- + | <a> M </a> <a> N </a> <a> O </a> | 1 | М | + -------------------------- + ------ + --------------- --------------- + 1 ряд в наборе (0,00 сек) + -------------------------- + ------ + --------------- --------------- + | XML | я | ExtractValue (xml, '// a [$ i]') | + -------------------------- + ------ + --------------- --------------- + | <a> M </a> <a> N </a> <a> O </a> | 2 | N | + -------------------------- + ------ + --------------- --------------- + 1 ряд в наборе (0,01 с) + -------------------------- + ------ + --------------- --------------- + | XML | я | ExtractValue (xml, '// a [$ i]') | + -------------------------- + ------ + --------------- --------------- + | <a> M </a> <a> N </a> <a> O </a> | 3 | O | + -------------------------- + ------ + --------------- --------------- + 1 ряд в наборе (0,01 с) + -------------------------- + ------ + --------------- --------------- + | XML | я | ExtractValue (xml, '// a [$ i]') | + -------------------------- + ------ + --------------- --------------- + | <a> M </a> <a> N </a> <a> O </a> | 4 | | + -------------------------- + ------ + --------------- --------------- + 1 ряд в наборе (0,02 сек) Запрос в порядке, затронуто 0 строк (0,02 сек)
Переменные параметров используются в выражениях XPath внутри хранимых подпрограмм, которые передаются как параметры, также подлежат строгой проверке.
В противном случае выражения, содержащие пользовательские переменные или локальные для хранимых программ переменные, должны соответствовать правилам для выражений XPath, содержащих переменные, как указано в спецификации XPath 1.0.
Примечание. В настоящее время пользовательская переменная, используемая для хранения выражения XPath, обрабатывается как пустая строка. Из-за этого невозможно сохранить выражение XPath в качестве пользовательской переменной.
ExtractValue (xml_frag, xpath_expr)
ExtractValue () принимает два строковых аргумента: фрагмент разметки XML xml_frag и выражение XPath xpath_expr (также известное как локатор); он возвращает текст (CDATA) первого текстового узла, который является потомком элементов или элементов, соответствующих выражению XPath. В MySQL 5.6.6 и более ранних версиях выражение XPath могло содержать не более 127 символов, ограничение было снято в MySQL 5.6.7.
Использование этой функции эквивалентно выполнению сопоставления с использованием xpath_expr после добавления / text (). Другими словами, ExtractValue ('Gopal', '/ a / b') и ExtractValue ('Gopal', '/ a / b / text ()') дают одинаковый результат.
Если найдено несколько совпадений, содержимое первого дочернего текстового узла каждого соответствующего элемента возвращается (в порядке совпадения) в виде одной строки, разделенной пробелом.
Если для выражения не найдено подходящего текстового узла (включая неявный / text ()) - по какой-то причине, пока xpath_expr допустим, а xml_frag состоит из элементов, которые правильно вложены и закрыты - возвращается пустая строка. Не делается различий между совпадением пустого элемента и отсутствием совпадения вообще.
Если вам нужно определить, не был ли найден соответствующий элемент в xml_frag или такой элемент был найден, но не содержал дочерних текстовых узлов, вам следует проверить результат выражения, использующего функцию XPath count (). Например, оба этих оператора возвращают пустую строку, как показано здесь:
пример
mysql> SELECT ExtractValue ('<a> </ b> </a>', '/ a / b'); + ------------------------------------- + | ExtractValue ('<a> </ b> </a>', '/ a / b') | + ------------------------------------- + | NULL | + ------------------------------------- + 1 ряд в наборе, 1 предупреждение (0,00 сек) mysql> SELECT ExtractValue ('<a> </ c> </a>', '/ a / b'); + ------------------------------------- + | ExtractValue ('<a> </ c> </a>', '/ a / b') | + ------------------------------------- + | NULL | + ------------------------------------- + 1 ряд в наборе, 1 предупреждение (0,00 сек) </ PRE> <p> Однако вы можете определить, действительно ли был соответствующий элемент, используя следующее: </ p> <pre class = "well"> mysql> SELECT ExtractValue ('<a> <b /> </a>', '/ a / b'); + ------------------------------------- + | ExtractValue ('<a> <b /> </a>', '/ a / b') | + ------------------------------------- + | | + ------------------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue ('<a> <b /> </a>', 'count (/ a / b)'); + -------------------------------------------- + | ExtractValue ('<a> <b /> </a>', 'count (/ a / b)') | + -------------------------------------------- + | 1 | + -------------------------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue ('<a> <c /> </a>', 'count (/ a / b)'); + -------------------------------------------- + | ExtractValue ('<a> <c /> </a>', 'count (/ a / b)') | + -------------------------------------------- + | 0 | + -------------------------------------------- + 1 ряд в наборе (0,00 сек)
ExtractValue () возвращает только CDATA и не возвращает ни тегов, которые могут содержаться в соответствующем теге, ни их содержимого (см. Результат, возвращенный как val1 в следующем примере).
MySQL> ВЫБРАТЬ -> ExtractValue ('<a> CAT <b> DOG </ b> </a>', '/ a') AS val1, -> ExtractValue ('<a> CAT <b> DOG </ b> </a>', '/ a / b') AS val2, -> ExtractValue ('<a> CAT <b> DOG </ b> </a>', '// b') AS val3, -> ExtractValue ('<a> CAT <b> DOG </ b> </a>', '/ b') AS val4, -> ExtractValue ('<a> CAT <b> DOG </ b> <b> EAT </ b> </a>', '// b') AS val5; + ------ + ------ + ------ + ------ + --------- + | val1 | val2 | val3 | val4 | val5 | + ------ + ------ + ------ + ------ + --------- + | CAT | СОБАКА | СОБАКА | | СОБАКА ЕСТЬ | + ------ + ------ + ------ + ------ + --------- + 1 ряд в наборе (0,00 сек)
Эта функция использует текущую сортировку SQL для сравнения с функции has (), выполняя ту же агрегацию сопоставления, что и другие строковые функции (например, CONCAT ()), с учетом сопоставимости их аргументов.
NULL возвращается, если xml_frag содержит элементы, которые не вложены или не закрыты должным образом, и генерируется предупреждение. Смотрите следующий пример:
mysql> SELECT ExtractValue ('<book> RAMAYANA </ X> <books />', '// book'); + ------------------------------------------------- ----- + | ExtractValue ('<book> RAMAYANA </ X> <books />', '// book') | + ------------------------------------------------- ----- + | NULL | + ------------------------------------------------- ----- + 1 ряд в наборе, 1 предупреждение (0,00 сек) mysql> ПОКАЗАТЬ ПРЕДУПРЕЖДЕНИЯ; + --------- + ------ + -------------------------------- ------------------------------ ---------------------------- + | Уровень | Код | Сообщение | + --------- + ------ + -------------------------------- ------------------------------ ---------------------------- + | Предупреждение 1525 | Неверное значение XML: 'ошибка синтаксического анализа в строке 1 поз 18:' </ X> 'un ожидается ('</ ook>' wanted) '| + --------- + ------ + -------------------------------- ------------------------------ ---------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue ('<book> RAMAYANA </ book> <books />', '// book'); + ------------------------------------------------- -------- + | ExtractValue ('<book> RAMAYANA </ book> <books />', '// book') | + ------------------------------------------------- -------- + | РАМАЯНА | + ------------------------------------------------- -------- + 1 ряд в наборе (0,00 сек)
Функция UpdateXML ()
Функция UpdateXML () используется для замены одной части заданного фрагмента разметки XML xml_target новым фрагментом XML new_xml, а затем возвращает измененный XML. Заменяемая часть xml_target соответствует выражению XPath xpath_expr, предоставленному пользователем. В MySQL 5.6.6 и более ранних версиях выражение XPath может содержать не более 127 символов. Это ограничение снято в MySQL 5.6.7. Если не найдено ни одного выражения, соответствующего xpath_expr, или найдено несколько совпадений, функция возвращает исходный XML-фрагмент xml_target. Все три аргумента должны быть строками.
mysql> SELECT -> UpdateXML ('<a> <b> CAT </ b> <d> </ d> </a>', '/ a', '<e> FOX </ e>') AS val1, -> UpdateXML ('<a> <b> CAT </ b> <d> </ d> </a>', '/ b', '<e> FOX </ e>') AS val2, -> UpdateXML ('<a> <b> CAT </ b> <d> </ d> </a>', '// b', '<e> FOX </ e>') AS val3, -> UpdateXML ('<a> <b> CAT </ b> <d> </ d> </a>', '/ a / d', '<e> FOX </ e>') AS val4 , -> UpdateXML ('<a> <d> </ d> <b> CAT </ b> <d> </ d> </a>', '/ a / d', '<e> FOX </ е> ') AS val5 -> / G *************************** 1. ряд ******************** ******* val1: <e> FOX </ e> val2: <a> <b> CAT </ b> <d> </ d> </a> val3: <a> <e> FOX </ e> <d> </ d> </a> val4: <a> <b> CAT </ b> <e> FOX </ e> </a> val5: <a> <d> </ d> <b> CAT </ b> <d> </ d> </a> 1 ряд в наборе (0,00 сек)
Ниже приведены описания и примеры некоторых основных выражений XPath:
/тег
Соответствует <tag /> тогда и только тогда, когда <tag /> является корневым элементом.
Пример: / a имеет совпадение в <a> <b /> </a>, потому что оно соответствует самому внешнему (корневому) тегу. Он не соответствует внутреннему элементу в <b> <a/> </ b>, потому что в этом случае он является потомком другого элемента.
/ Tag1 / tag2
Соответствует <tag2 /> тогда и только тогда, когда он является дочерним по отношению к <tag1 />, а <tag1 /> является корневым элементом.
Пример: / a / b соответствует элементу b во фрагменте XML <a> <b /> </a>, поскольку он является дочерним для корневого элемента a. У него нет совпадения в <b> <a/> </ b>, потому что в этом случае b является корневым элементом (и, следовательно, дочерним по отношению к другому элементу). Также выражение XPath не имеет соответствия в <a> <c> <b /> </ c> </a>; здесь b является потомком а, но на самом деле не является потомком а.
Эта конструкция может быть расширена до трех или более элементов. Например, выражение XPath / a / b / c соответствует элементу c во фрагменте <a> <b> <c /> </ b> </a>.
//тег
Соответствует любому экземпляру <tag>.
Пример: // a соответствует элементу a в любом из следующих: <a> <b> <c /> </ b> </a>; <С> <a> <б /> </a> </ B>; <С> <б> <a/> </ B> </ с>.
// можно комбинировать с /. Например, // a / b соответствует элементу b в любом из фрагментов <a> <b /> </a> или <a> <b> <c /> </ b> </a>
Примечание // тег является эквивалентом тега / потомок-или-себя :: * /. Распространенной ошибкой является путаница с тегом / downndant-or-self ::, хотя последнее выражение может на самом деле привести к очень разным результатам, как можно видеть здесь:
mysql> SET @xml = '<books> <book id = "bk101"> <author> Селеста Нг </ author> <title> Ева Я никогда не говорил тебе </ title> <жанр> роман </ genre> <цена> $ 16.17 </ цена> < / book> <book id = "bk102"> <author> Фил Клэй </ author> <title> ERedeployment </ tit le> <genre> war writing </ genre> <цена> $ 16.17 </ price> </ book> </ books> '; Запрос в порядке, затронуто 0 строк (0,00 с) mysql> SELECT @xml; + ------------------------------------------------- ------------------------------ -------------------------------------------------- ------------------------------ -------------------------------------------------- ------------------------------ ------------------------------------------------- + | @xml | + ------------------------------------------------- ------------------------------ -------------------------------------------------- ------------------------------ -------------------------------------------------- ------------------------------ ------------------------------------------------- + | <books> <book id = "bk101"> <author> Селеста Нг </ author> <title> Все, что я никогда не делаю old You </ title> <жанр> роман </ genre> <цена> 16,17 $ </ цена> </ book> <book id = "b k102 "> <author> Phil Klay </ author> <title> ERedeployment </ title> <genre> war wri Ting </ genre> <цена> $ 16,17 </ цена> </ book> </ books> | + ------------------------------------------------- ------------------------------ -------------------------------------------------- ------------------------------ -------------------------------------------------- ------------------------------ ------------------------------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue (@xml, '// book [1]'); + --------------------------------- + | ExtractValue (@xml, '// book [1]') | + --------------------------------- + | | + --------------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue (@xml, '// book [0]'); + --------------------------------- + | ExtractValue (@xml, '// book [0]') | + --------------------------------- + | | + --------------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue (@xml, '// author [1]'); + ----------------------------------- + | ExtractValue (@xml, '// author [1]') | + ----------------------------------- + | Селеста Нг Фил Клай | + ----------------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue (@xml, '// author [2]'); + ----------------------------------- + | ExtractValue (@xml, '// author [2]') | + ----------------------------------- + | | + ----------------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue (@xml, '// Потомок-или-сам :: * / author [1]'); + ------------------------------------------------- -------- + | ExtractValue (@xml, '// Потомок или или сам :: :: / author [1]') | + ------------------------------------------------- -------- + | Селеста Нг Фил Клай | + ------------------------------------------------- -------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue (@xml, '// Потомок-или-сам :: * / author [2]'); + ------------------------------------------------- -------- + | ExtractValue (@xml, '// потомок-или-сам :: * / author [2]') | + ------------------------------------------------- -------- + | | + ------------------------------------------------- -------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue (@xml, '// Потомок-или-сам :: автор [1]'); + ------------------------------------------------- ------ + | ExtractValue (@xml, '// Потомок-или-Сам :: Автор [1]') | + ------------------------------------------------- ------ + | Селеста Нг Фил Клай | + ------------------------------------------------- ------ + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue (@xml, '// Потомок-или-сам :: автор [2]'); + ------------------------------------------------- ------ + | ExtractValue (@xml, '// Потомок-или-Сам :: Автор [2]') | + ------------------------------------------------- ------ + | Фил Клэй | + ------------------------------------------------- ------ + 1 ряд в наборе (0,00 сек)
- Оператор * действует как «подстановочный знак», который соответствует любому элементу. Например, выражение / * / b соответствует элементу b в любом из фрагментов XML или в <c> <b /> </ c>. Тем не менее, выражение не дает совпадения во фрагменте, потому что b должен быть потомком некоторого другого элемента. Подстановочный знак можно использовать в любой позиции: выражение / * / b / * будет соответствовать любому дочернему элементу ab, который сам не является корневым элементом.
- Вы можете сопоставить любой из нескольких локаторов, используя | (СОЮЗ) оператор. Например, выражение // b | // c соответствует всем элементам b и c в целевом объекте XML.
- Также возможно сопоставить элемент на основе значения одного или нескольких его атрибутов. Это делается с помощью синтаксического тега [@ attribute = "value"]. Например, выражение // b [@ id = "idB"] соответствует второму элементу b во фрагменте <a> <b id = "idA" /> <c /> <b id = "idB" /> < / а>. Для сопоставления с любым элементом, имеющим attribute = "value", используйте выражение XPath // * [attribute = "value"].
Чтобы отфильтровать несколько значений атрибутов, просто используйте несколько предложений сравнения атрибутов подряд. Например, выражение // b [@ c = "x"] [@ d = "y"] соответствует элементу <bc = "x" d = "y" />, встречающемуся в любом месте данного фрагмента XML.
Чтобы найти элементы, для которых один и тот же атрибут соответствует любому из нескольких значений, вы можете использовать несколько локаторов, объединенных | оператор. Например, чтобы сопоставить все элементы b, чьи атрибуты c имеют одно из значений 23 или 17, используйте выражение // b [@ c = "23"] | // b [@ c = "17"]. Вы также можете использовать логический или оператор для этой цели: // b [@ c = "23" или @ c = "17"].
Примечание Разница между или и | это или присоединяется к условиям, в то время как | объединяет наборы результатов.
Ограничения XPath . Синтаксис XPath, поддерживаемый этими функциями, в настоящее время имеет следующие ограничения:
- Сравнение между узлами и узлами (например, '/ a / b [@ [email protected] ]') не поддерживается.
- Поддерживаются все стандартные операторы сравнения XPath.
- Относительные выражения локатора разрешаются в контексте корневого узла. Например, рассмотрим следующий запрос и результат:
mysql> SELECT ExtractValue ( -> '<a> <bc = "1"> M </ b> <bc = "2"> A </ b> </a>', -> 'a / b' ->) КАК результат; + -------- + | результат | + -------- + | МА | + -------- + 1 ряд в наборе (0,00 сек)
В этом случае локатор a / b преобразуется в / a / b.
Относительные локаторы также поддерживаются в предикатах. В следующем примере d [../@ c = "1"] разрешается как / a / b [@ c = "1"] / d:
mysql> SELECT ExtractValue ( -> '<a> '> <bc = "1"> <d> Z </ d> </ b> '> <bc = "2"> <d> Z </ d> </ b> '> </a>', -> 'a / b / d [../@ c = "1"]') -> КАК результат; + -------- + | результат | + -------- + | Z | + -------- + 1 ряд в наборе (0,00 сек)
- Локаторы с префиксом выражений, которые оценивают как скалярные значения, включая ссылки на переменные, литералы, числа и вызовы скалярных функций, не допускаются, и их использование приводит к ошибке.
- Оператор :: не поддерживается в сочетании с типами узлов, такими как следующие:
- осевой :: комментарий ()
- ось :: текст ()
- Ось :: обработка-инструкции ()
- Ось :: узел ()
Тем не менее, тесты имен (такие как axis :: name и axis :: *) поддерживаются, как показано в следующих примерах:
mysql> SELECT ExtractValue (''' / Красные / ч л.д. :: синий '); + ------------------------------------------------- ----------------------------- + | EXTRACTVALUE (» Икс Y ',' / red / child :: blue ') | + ------------------------------------------------- ----------------------------- + | х | + ------------------------------------------------- ----------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT ExtractValue (' Икс Y '' / Красные / ч л.д. :: * '); + ------------------------------------------------- -------------------------- + | EXTRACTVALUE (» Икс Y ',' / red / child :: * ') | + ------------------------------------------------- -------------------------- + | ху | + ------------------------------------------------- -------------------------- + 1 ряд в наборе (0,00 сек) Икс Y
- Навигация «вверх-вниз» не поддерживается в тех случаях, когда путь ведет «выше» корневого элемента. То есть, вы не можете использовать выражения, которые соответствуют потомкам предков данного элемента, где один или несколько предков текущего элемента также являются предком корневого элемента.
- Следующие функции XPath не поддерживаются или имеют известные проблемы, как указано:
- Я бы()
- языки ()
- местное имя ()
- название()
- Пространство имен-URI ()
- нормализуют-пространство ()
- начинается с()
- строка ()
- подстрока-после того, как ()
- подстрока-ранее ()
- переведите()
- Следующие оси не поддерживаются:
- следующая-родственный
- следующий
- предшествующее-родственный
- предшествующий
Выражения XPath, передаваемые в качестве аргументов ExtractValue () и UpdateXML (), могут содержать символ двоеточия («:») в селекторах элементов, что позволяет использовать их с разметкой с использованием нотации пространств имен XML. Например:
mysql> SET @xml = '<red> 100 <black: green> 200 <white> 300 </ white> <yellow: pink> 400 </ y ellow: розовый> </ черный: зеленый> </ красный> '; Запрос в порядке, затронуто 0 строк (0,00 с) mysql> SELECT ExtractValue (@xml, '// yellow: pink'); + ------------------------------------- + | ExtractValue (@xml, '// yellow: pink') | + ------------------------------------- + | 400 | + ------------------------------------- + 1 ряд в наборе (0,00 сек) mysql> SELECT UpdateXML (@xml, '// black: green', '<brown: redish> 500 </ brown: redish> «); + ------------------------------------------------- --------------------- + | UpdateXML (@xml, '// black: green', '<brown: redish> 500 </ brown: redish>') | + ------------------------------------------------- --------------------- + | <красный> 100 <коричневый: красноватый> 500 </ коричневый: красноватый> </ красный> | + ------------------------------------------------- --------------------- + 1 ряд в наборе (0,00 сек)
В некоторых отношениях это похоже на то, что разрешено Apache Xalan и некоторыми другими синтаксическими анализаторами, и намного проще, чем требование объявления пространства имен или использование функций namespace-uri () и local-name ().
Обработка ошибок. Как для ExtractValue (), так и для UpdateXML () используемый локатор XPath должен быть допустимым, а искомый XML должен состоять из элементов, которые правильно вложены и закрыты. Если локатор недействителен, генерируется ошибка:
mysql> SELECT ExtractValue ('автор ',' / & book '); ОШИБКА 1105 (HY000): синтаксическая ошибка XPATH: '& book'
Если xml_frag не состоит из элементов, которые правильно вложены и закрыты, возвращается NULL и генерируется предупреждение, как показано в этом примере:
mysql> SELECT ExtractValue ('& lt; book & gt; author & lt; / book & gt; & lt; ERedeployment', '// book'); + ------------------------------------------------- ------------ + | ExtractValue ('& lt; book & gt; author & lt; / book & gt; & lt; ERedeployment', '// book') | + ------------------------------------------------- ------------ + | NULL | + ------------------------------------------------- ------------ + 1 ряд в наборе, 1 предупреждение (0,00 сек) mysql> ПОКАЗАТЬ ВНИМАНИЕ / ОШИБКА 1064 (42000): у вас ошибка в синтаксисе SQL; проверьте руководство, которое соответствует версии вашего сервера MySQL для правильного синтаксиса для использования рядом с 'WARNI NG 'в строке 1 mysql> SELECT ExtractValue ('& lt; book & gt; author & lt; / book & gt; & lt; ERedeployment / & gt;', '// book'); + ------------------------------------------------- -------------- + | ExtractValue ('& lt; book & gt; author & lt; / book & gt; & lt; ERedeployment / & gt;', '// book') | + ------------------------------------------------- -------------- + | автор | + ------------------------------------------------- -------------- + 1 ряд в наборе (0,00 сек)
Заменяющий XML, используемый в качестве третьего аргумента для UpdateXML (), не проверяется, чтобы определить, состоит ли он исключительно из элементов, которые правильно вложены и закрыты.
XPath Инъекция. внедрение кода происходит, когда вредоносный код вводится в систему для получения несанкционированного доступа к привилегиям и данным. Он основан на использовании предположений, сделанных разработчиками относительно типа и содержания данных, вводимых пользователями. XPath не является исключением в этом отношении.
Распространенный сценарий, в котором это может произойти, - это случай приложения, которое обрабатывает авторизацию, сопоставляя комбинацию имени для входа и пароля с найденными в файле XML, используя выражение XPath, подобное следующему:
// user [login / text () = 'neapolitan' и password / text () = '1c3cr34m'] / attribute :: id
Это XPath-эквивалент SQL-оператора, подобного следующему:
ВЫБЕРИТЕ ID ОТ ПОЛЬЗОВАТЕЛЕЙ, ГДЕ login = 'neapolitan' И пароль = '1c3cr34m';
На входе проверки не выполняются. Это означает, что злонамеренный пользователь может «замкнуть» тест, введя 'или 1 = 1 для имени входа и пароля, что приведет к оценке $ xpath, как показано здесь:
// пользователь [логин / текст () = '' или 1 = 1 и пароль / текст () = '' или 1 = 1] / attribute :: id
Поскольку выражение в квадратных скобках всегда оценивается как true, оно фактически совпадает с этим, что соответствует атрибуту id каждого пользовательского элемента в документе XML:
// пользователь / атрибут :: идентификатор
Один из способов обойти эту конкретную атаку - просто заключить в кавычки имена переменных, которые необходимо интерполировать в определении $ xpath, и принудительно преобразовать значения, передаваемые из веб-формы, в строки:
$ xpath = "// user [login / text () = '$ login' и password / text () = '$ password'] / attribute :: id";
Это та же самая стратегия, которая часто рекомендуется для предотвращения атак с использованием SQL-инъекций. В целом, для предотвращения атак внедрения XPath вы должны следовать тем же правилам, что и для предотвращения внедрения SQL:
- Никогда не принимал непроверенные данные от пользователей в вашем приложении.
- Проверьте все представленные пользователем данные для типа; отклонить или преобразовать данные неправильного типа
- Тест числовых данных для значений вне диапазона; усекать, округлять или отклонять значения, выходящие за пределы диапазона. Проверьте строки на наличие недопустимых символов и либо удалите их, либо отклоните ввод, содержащий их.
- Не выводить явную ошибку сообщения, которые могут предоставить неавторизованному пользователю подсказки, которые могут быть использованы для взлома системы; зарегистрируйте их в файл или таблицу базы данных.
Подобно тому, как атаки с использованием SQL-инъекций можно использовать для получения информации о схемах базы данных, так же можно использовать XPath-инъекцию для обхода XML-файлов с целью выявления их структуры, как обсуждалось в статье Амит Кляйн Blind XPath Injection (PDF-файл, 46 КБ).
Также важно проверить выходные данные, отправляемые обратно клиенту. Рассмотрим, что может произойти, когда мы используем функцию MySQL ExtractValue ():
mysql> SELECT ExtractValue ( -> LOAD_FILE ('test.xml'), -> '// user [login / text () = "" или 1 = 1 и пароль / text () = "" или 1 = 1] / attribute :: Я бы' ->) AS id; + ------ + | id | + ------ + | NULL | + ------ + 1 ряд в наборе (0,03 сек)
Предыдущая: Информационные функции MySQL
Далее: Разные функции MySQL
Новый контент: Composer: менеджер зависимостей для PHP , R программирования