开发者

xpath xsl find when parent have attribute equal to value

These is my xml:

<root>
<node>
 <element id='1'>
   <subelement>val</subelement>
</element>
<element id='2'>
   <subelement>val</subelement>
</element>
</node>

i don开发者_StackOverflow社区't know the parent name and 'node' name

The solution descendant::*[ @id= '1' ]/subelement


i don't know the parent name and 'node' name

The solution descendant::*[ @id= '1' ]/subelement

Using descendant::* can be extremely inefficient as this causes the complete sub-tree rooted by the current node to be traversed.

Here is an efficient XSLT solution:

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>
 <xsl:key name="kElByParentId" match="*" use="../@id"/>

 <xsl:template match="/">
   <xsl:copy-of select="key('kElByParentId', '1')"/>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document (corrected to be well-formed):

<root>
    <node>
        <element id='1'>
            <subelement>val</subelement>
        </element>
        <element id='2'>
            <subelement>val</subelement>
        </element>
    </node>
</root>

produces the wanted, correct result:

<subelement>val</subelement>

Do note: The use of keys (<xsl:key> and the key() function) makes this a really efficient solution -- with sublinear (even close to constant) time complexity.


This would match the condition in the subject:

//element/@id eq //element/subelement/text()

But what would you like to do with this? Perhaps you need this to be more generic?


If you know how deep it is then you can just use * as in:

/*/*/element[@id = '1']/subelement
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜