Вопрос XML XPath

#xml #xpath

#xml #xpath — путь #xpath

Вопрос:

  <categories>
<member>
    <name> Ants </name>
    <size> 8 </size>
    <submember>
        <structure>
            <name>Acrobat Ants </name>
            <size>Slightly over 1/8" </size>
            <color>Tan, red with heart shaped abdomen </color>
            <habitat>Inside moist wood</habitat>
            <found>Throughout the US</found>
            <desc></desc>
            <productLink> </productLink>
        </structure>

        <structure>
            <name>Argentine Ant </name>
            <size>About 1/16" </size>
            <color>Light to dark brown </color>
            <habitat>Shallow areas with moist soil</habitat>
            <origin>Argentina and Brazil</origin>
            <desc></desc>
            <productLink></productLink>
        </structure>    

        <structure>
            <name>Carpenter Ants </name>
            <size>1/4-1/2" </size>
            <color>Varies</color>
            <Habitat>Inside decayed or moist wood</Habitat>
            <Found>Throughout the US</Found>
            <desc>C</desc>
            <productLink></productLink>
        </structure>
     </submember>
 </member>
 </categories>
  

Допустим, у меня есть XML-файл, подобный этому (фактический xml намного длиннее этого), тогда как мне получить структуру «Ants», используя xpath?

Комментарии:

1. Хороший вопрос, 1. Смотрите мой ответ для двух выражений XPath, которые выбирают нужные узлы. 🙂

Ответ №1:

Я предполагаю, что вы хотите, member который содержит Ants в качестве Name . Этого должно быть достаточно:

 /categories/member[name=' Ants ']
  

Обратите внимание, что кавычки содержат пробелы, необходимые для имени. Пробелы важны в XML, поэтому пробелы вокруг Ants также являются частью содержимого. В противном случае вы могли бы сначала нормализовать пробелы, что эффективно устраняет избыточные пробелы перед сравнением.

 /categories/member[normalize-space(name)='Ants']
  

Как указывает Алехандро, вам могут понадобиться structure потомки под Ants элементом. Тогда вам нужно будет копнуть немного дальше.

 /categories/member[normalize-space(name)='Ants']/submember/structure
  

Комментарии:

1. M: При этом выбираются member элементы, а не structure элементы

2. @Alejandro: И это то, чего, как я предположил, он хотел. Мне было не очень ясно, какие элементы он хотел. Но теперь, когда вы указали на это, я думаю, ему понадобились бы structure элементы. Первоначально я прочитал это как «Я хочу вещь с именем «Ants», я не знаю, как это назвать, но это похоже на структуру». Я не понимал, что существуют элементы, которые были названы structure , меня беспокоило только имя ‘Ants’ . 🙂

Ответ №2:

Допустим, у меня есть XML-файл, подобный этому (фактический xml намного длиннее этого), тогда как мне получить структуру «Ants», используя xpath?

Я предполагаю, что вы хотите выбрать любой, structure с дочерним name элементом, строковое значение которого содержит строку «Ants».

Использовать:

   /*/*/*/structure[contains(name, 'Ants')]
  

При этом выбирается любой structure элемент, у которого есть дочерний name элемент, содержащий строку «Ants», и который ( sructure элемент) является дочерним по отношению к любому элементу, который является дочерним по отношению к любому элементу, который является дочерним по отношению к верхнему элементу XML-документа.

Или используйте:

   /*/*/*/structure[contains(concat(name,' '), ' Ants ')]
  

При этом выбирается structure элемент, который удовлетворяет всем требованиям, как в предыдущем выражении, за исключением того, что его name дочерний элемент должен содержать «Ants», перед которым стоит пробел и либо за которым следует пробел, либо являющийся конечной подстрокой полного строкового значения name .

Ответ №3:

Вот несколько дополнений к (хорошему) ответу @Jeff’s. Это нацелено на все <structure> элементы ниже, <member> имя которых содержит Ants (с учетом начальных / завершающих пробелов):

 /categories/member[normalize-space(name)='Ants']/submember/structure
  

Или только первый:

 /categories/member[normalize-space(name)='Ants']/submember/structure[1]
  

Просто Carpenter Ants :

 /categories/member[normalize-space(name)='Ants']/submember/structure[normalize-space(name)='Carpenter Ants']
  

И так далее…

Вы должны попытаться обобщить их для своих собственных целей.