Получить узлы, которые не имеют определенного предка xml xpath - PullRequest
2 голосов
/ 16 мая 2011

Я хотел бы иметь xpath, который получает узлы, у которых нет предка, который является первым потомком определенного узла.

Давайте предположим, что у нас есть XML-документ, подобный этому:

<a>
  <b>This node</b>
  <c>
    <a>
      <b>not this</b>
      <g>
        <b>not this</b>
      </g>
    </a>
    <a>
      <b>This node</b>
      <c/>
    </a>
  </c>
</a>


<a>
  <c>
    <a>
      <b>not this</b>
    </a>
    <a>
      <b>This node</b> 
    </a>
    <a>
      <b>This node</b> 
    </a>
    <a>
      <b>This node</b> 
    </a>
  </c>
</a>


<d>
  <b>This node</b>
</d>

Я хотел бы выбрать все узлы b в документе, которые не имеют в качестве узла-предка //a/c/a[1].

1 Ответ

8 голосов
/ 16 мая 2011

Я хотел бы выбрать все узлы b в документе, которые не имеют в качестве узла-предка //a/c/a[1]

Использовать это выражение XPath :

//b[not(ancestor::a
             [parent::c[parent::a]
            and
              not(preceding-sibling::a)
             ]
       )
   ]

Выбирает все элементы b в документе, у которых нет предка a, у которого есть родительский элемент c, у которого есть родительский элемент a и aпредок, у которого родительский элемент c не является первым a дочерним по отношению к его родительскому элементу.

С учетом следующего XML-документа (на основе предоставленного, но сделанного корректным и также помещенногоидентифицирующий текст в узлах, которые должны быть выделены):

<t>
    <a>
        <b>This node 1</b>
        <c>
            <a>
                <b>not this</b>
                <g>
                    <b>not this</b>
                </g>
            </a>
            <a>
                <b>This node 2</b>
                <c/>
            </a>
        </c>
    </a>
    <a>
        <c>
            <a>
                <b>not this</b>
            </a>
            <a>
                <b>This node 3</b>
            </a>
            <a>
                <b>This node 4</b>
            </a>
            <a>
                <b>This node 5</b>
            </a>
        </c>
    </a>
    <d>
        <b>This node 6</b>
    </d>
</t>

выбраны именно те элементы, которые нужны 6 b.

Проверка с использованием XSLT :

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

 <xsl:template match="/">
 <xsl:copy-of select=
 "//b[not(ancestor::a
             [parent::c[parent::a]
            and
              not(preceding-sibling::a)
             ]
         )
     ]

 "/>
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к вышеуказанному документу XML, именно нужные элементы b выбираются и копируются в выходной файл.Требуемый, правильный результат выдается :

<b>This node 1</b>
<b>This node 2</b>
<b>This node 3</b>
<b>This node 4</b>
<b>This node 5</b>
<b>This node 6</b>
...