tags:

views:

25

answers:

3

These is my xml:

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

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

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

A: 

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?

Marcin Cylke
i don't know the 'element' name
Haroldis
A: 

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

/*/*/element[@id = '1']/subelement
null
+2  A: 

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"&gt;
 <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.

Dimitre Novatchev
@Dimitre: +1 Good answer.
Alejandro