2009-07-21 4 views
2

У меня возникли проблемы с написанием выражения XPath, чтобы выбрать узлы, которые содержат определенные элементы, в то же время исключая братьев и сестер этого элемента, которые меня не интересуют. Я подозреваю, что это невозможно сделать с XPath, и что я необходимо будет использовать XSLT.XPath selection

Используя этот исходный документ

<items> 
    <item id="foo1"> 
     <attr1>val1</attr1> 
     <attr2>val2</attr2> 
     <attr3>val3</attr3> 
     <interestingAttribute>val4</interestingAttribute> 
    </item> 
    <item id="foo2"> 
     <attr1>val5</attr1> 
     <attr2>val6</attr2> 
     <attr3>val7</attr3> 
    </item> 
    <item id="foo3"> 
     <attr1>val8</attr1> 
     <attr2>val9</attr2> 
     <attr3>val10</attr3> 
     <interestingAttribute>val11</interestingAttribute> 
    </item> 
</items> 

Я хотел бы, чтобы произвести этот результат

<items> 
    <item id="foo1"> 
     <interestingAttribute>val4</interestingAttribute> 
    </item> 
    <item id="foo3"> 
     <interestingAttribute>val11</interestingAttribute> 
    </item> 
</items> 

это может быть сделано с помощью XPath? Если нет, то какую XSLT-трансформацию я должен использовать?

+0

Вы хотите создать весь xml, который у вас есть в результате? Или вы просто хотите, чтобы эти конкретные узлы из xpath выполнялись в вашей кодовой базе? –

+0

Я бы предпочел сгенерировать весь XML-документ. Но если есть решение XPath, которое исключает элемент , это тоже хорошо. – Chris

ответ

4

XPath используется для выбора определенных узлов, и он не даст вам древовидной структуры, как вы хотите. В лучшем случае вы можете получить список узлов из него, и из списка узлов вы можете получить древовидную структуру. Если все, что вы действительно хотите здесь, чтобы выбрать интересные атрибуты, вы можете попробовать это XPath:

/items/item/interestingAttribute 

Если вы хотите создать дерево, вам понадобится XSLT. Этот шаблон должен сделать это:

<xsl:template match="/items"> 
    <xsl:copy> 
     <xsl:for-each select="item[interestingAttribute]"> 
      <xsl:copy> 
       <xsl:copy-of select="@* | interestingAttribute"/> 
      </xsl:copy> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 
+0

Исправлены опечатки, спасибо, что указали их – Chris

2

Это будет выбирать только <item> S, которые имеют <interestingAttribute> детей:

/items/item[interestingAttribute] 

Или вы можете выбрать <interestingAttribute> сами элементы, как так:

/items/item/interestingAttribute 

Эти два выражения даст вам обратно node- set, список узлов XML. Если вы действительно пытаетесь преобразовать один документ в другой, вы, вероятно, захотите использовать XSLT, но помните, что XPath является основным компонентом XSLT, поэтому вы, безусловно, будете использовать выражения XPath, подобные приведенным выше, для управления преобразованием.