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
精彩评论