Как найти расположение двух узлов с одинаковыми именами, вложенных в два разных тега? - PullRequest
2 голосов
/ 12 мая 2011

У меня есть следующий XML:

<employees>
   <employee>   <!--forgot to include an attribute-->
      <name>John</name>
      <jobs>
          <job>Writer</job>
          <job>Artist</job>
     </jobs>
   </employee>
   <employee>
      <name>John</name>
      <jobs>
          <job>Engineer</job>
          <job>Editor</job>
     </jobs>
   </employee>
</employees>

Если я хочу получить работу людей с именем = "Джон", XPath возвращает все четыре работы, принадлежащие одному "Джону". Я хочу, чтобы 2 + 2 работы выполнялись двумя разными "Джонами".

Я использую выражение XPath

"//employees/employee[name='John']/jobs/job/text()"

Есть ли способ в XPath в Java с использованием счетчика или какой-либо другой функции, чтобы сделать это ??

Ответы [ 2 ]

2 голосов
/ 12 мая 2011

XPath является (только) языком запросов для документов XML - результат оценки выражения XPath никогда не является измененным узлом - только XPath не меняет структуру и / или содержимое любого узел.

То, что вы хотите вернуть - это модифицированные <employee> элементы только с их дочерним элементом <jobs>, и это невозможно сделать только с помощью XPath.

Ближайшим к тому, что вы хотите, является :

/*/employee[name='John']/jobs

Выбирает следующее :

    <jobs>
        <job>Writer</job>
        <job>Artist</job>
    </jobs>
    <jobs>
        <job>Engineer</job>
        <job>Editor</job>
    </jobs>

Я полагаю, что с помощью этого преобразования XSLT вы можете добиться желаемого результата совершенно просто :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
     <xsl:copy-of select=
     "/*/employee[name='John']/node()[not(self::comment())]"/>
 </xsl:template>
 </xsl:stylesheet>

когда это преобразование применяется к предоставленному документу XML :

<employees>
    <employee>
        <!--forgot to include an attribute-->
        <name>John</name>
        <jobs>
            <job>Writer</job>
            <job>Artist</job>
        </jobs>
    </employee>
    <employee>
        <name>John</name>
        <jobs>
            <job>Engineer</job>
            <job>Editor</job>
        </jobs>
    </employee>
</employees>

желаемый, правильный результат выдается :

<name>John</name>
<jobs>
   <job>Writer</job>
   <job>Artist</job>
</jobs>
<name>John</name>
<jobs>
   <job>Engineer</job>
   <job>Editor</job>
</jobs>
0 голосов
/ 12 мая 2011

XPath всегда будет возвращать плоский список, независимо от того, где найдены узлы, поэтому вы просто получаете 4 фрагмента текста.Если вы хотите сгруппировать их по их родительским узлам, вам нужно сначала найти Johns и с этими результатами выполнить вложенный цикл - для каждого John выполните XPath для заданий, начиная с этого узла.Как вы хотите сгруппировать их в Java, зависит от вас - возможно, Карта строки (имя) в Список строки (работа).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...