2013-05-25 4 views
0

У меня есть этот исходный XML-дерево:выражение XPath, чтобы исключить некоторые дочерние узлы

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <foo> 
    <bar> 
     <baz> 
     <item> 
      <methods> 
      <item> 
       <id>1</id> 
      </item> 
      </methods> 
      <id>1</id> 
     </item> 
     <item> 
      <methods> 
      <item> 
       <id>19</id> 
      </item> 
      </methods> 
      <id>2</id> 
     </item> 
     </baz> 
    </bar> 
    </foo> 
    <bar_method> 
    <root> 
     <bla id="1"> 
     <methods> 
      <method id="1"> 
      <calc md="ck" /> 
      <tm m="14" /> 
      <price_list> 
       <price mse="0"> 
       <ins re="0" /> 
       </price> 
      </price_list> 
      </method> 
      <method id="2"> 
      <calc md="qck" /> 
      <tm m="4" /> 
      <price_list> 
       <price mse="1"> 
       <ins re="0" /> 
       </price> 
      </price_list> 
      </method> 
     </methods> 
     </bla> 
     <bla id="2"> 
     <methods> 
      <method id="19"> 
      <calc md="dd" /> 
      <tm m="3" /> 
      <price_list> 
       <price mse="01"> 
       <ins re="0" /> 
       </price> 
      </price_list> 
      </method> 
     </methods> 
     </bla> 
    </root> 
    </bar_method> 
</root> 

Теперь нужно поместить фрагмент этого дерева в переменной с помощью XPath. Фрагмент должен выглядеть следующим образом:

<bla id="1"> 
    <methods> 
    <method id="1"> 
     <calc md="ck" /> 
     <tm m="14" /> 
     <price_list> 
     <price mse="0"> 
      <ins re="0" /> 
     </price> 
     </price_list> 
    </method> 
    </methods> 
</bla> 
<bla id="2"> 
    <methods> 
    <method id="19"> 
     <calc md="dd" /> 
     <tm m="3" /> 
     <price_list> 
     <price mse="01"> 
      <ins re="0" /> 
     </price> 
     </price_list> 
    </method> 
    </methods> 
</bla> 

Это bla узлов исключая method узлов, id атрибутов которых не хватает в /root/foo/bar/baz/item/methods/item/id. Я использую следующее выражение, но он выбирает все узлы с дубликатами:

<xsl:variable name="meth" select="/root/bar_method/root//*[not(name() = 'method' and count(/root/foo/bar/baz//methods/item[id = @id]) = 0)]" /> 
+0

Почему вам нужно разместить фрагмент в переменной. Какой результат вы хотите получить от XSL? Похоже, вам нужны шаблоны для меня. –

+0

Мне просто интересно, возможно ли это. –

+0

Похоже, вы хотите, чтобы все элементы 'bla' и только первый элемент' methods/method' внутри каждого из них. Это правильно? Вы не можете сделать это в одном выражении XPath, потому что вы можете ограничить только выбранные элементы - вы также не можете отфильтровать некоторых своих потомков. – Borodin

ответ

0

Похоже, вы хотите, чтобы все bla элементы и только первый methods/method элемент внутри каждого из них. Это правильно?

Вы не можете сделать это в одном выражении XPath, потому что вы можете ограничить только выбранные элементы - вы также не можете отфильтровать некоторые из их потомков. Но можно использовать шаблоны.

Эта таблица стилей создает переменную $meth и выводит ее с использованием copy-of.

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:strip-space elements="*"/> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 

    <xsl:template match="/"> 
    <xsl:variable name="meth"> 
     <xsl:apply-templates select="root/bar_method/root/bla"/> 
    </xsl:variable> 
    <xsl:copy-of select="$meth"/> 
    </xsl:template> 

    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="methods"> 
    <xsl:copy> 
     <xsl:apply-templates select="method[1]"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

выход

<bla id="1"> 
    <methods> 
     <method id="1"> 
     <calc md="ck"/> 
     <tm m="14"/> 
     <price_list> 
      <price mse="0"> 
       <ins re="0"/> 
      </price> 
     </price_list> 
     </method> 
    </methods> 
</bla> 
<bla id="2"> 
    <methods> 
     <method id="19"> 
     <calc md="dd"/> 
     <tm m="3"/> 
     <price_list> 
      <price mse="01"> 
       <ins re="0"/> 
      </price> 
     </price_list> 
     </method> 
    </methods> 
</bla> 
1

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

Если вы хотите создать дерево, отличное от дерева ввода, вам нужны XSLT или XQuery.

Смежные вопросы