1

Hello I got a question regarding looping through an xml document and return the sub-sub children (e.g. prop1, prop2, item1, item2, country1, country2) of the document element with their beloning children (e.g. person, name, address) element names.

I have the following XML document:

<data>
    <person>
        <properties>
            <prop1>test</prop1>
            <prop2>test</prop2>
        </properties>
    </person>
    <name>
        <properties>
            <item1>test</item1>
            <item2>test</item2>
        </properties>
    </name>
    <address>
        <properties>
            <country1>test</country1>
            <country2>test</country2>
        </properties>       
    </address>
</data>

The desired output that I want is:

person prop1
person prop2
name item1
name item2
address country1
address country2

I managed to produce the following list: person name address

applying this XSLT transformation.:

<xsl:template match="*/*|@*">  
   <xsl:value-of select="name()"/>  
   <xsl:apply-templates select="@*"/>
 </xsl:template>

Can anyone tell me what I should do? Thanks

2
  • Can you better specify what are "the desired node names"? Are they children of properties, or grand-grandchildren of the root element, or elements that contain text, or ... ? Commented Jun 3, 2016 at 13:41
  • yes look at my updated answer @michael.hor257k Commented Jun 3, 2016 at 13:45

3 Answers 3

2

I believe you want to do:

XSLT 1.0

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

<xsl:template match="/data">
    <xsl:for-each select="*/properties/*">
        <xsl:value-of select="name(../..)" />
        <xsl:text> </xsl:text>
        <xsl:value-of select="name()"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

1 Comment

That is exactly what I wanted! Thank you!
1

Try this XSLT-1.0 snippet:

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

  <xsl:template match="text()" />

  <xsl:template match="/data/*">
    <xsl:for-each select="properties/*">
      <xsl:value-of select="concat(name(../..),' ',name(),'&#10;')" />
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

Output is:

<?xml version="1.0"?>
person prop1
person prop2
name item1
name item2
address country1
address country2

Comments

1

As short and simple as this completely pull style transformation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="/*/*/*/*">
    <xsl:value-of select="concat(name(../..),' ',name(),'&#xA;')"/>
  </xsl:template>
</xsl:stylesheet>

Note:

It is not necessary to use any <xsl:for-each> -- just leave the XSLT processing model and the XSLT processor do their job.

3 Comments

Thank you. Can you perhaps explain what this does? Why do you have to have /*/*/*/*
@Rotan075, The XPath expression (in this case also match-pattern) /*/*/*/* selects all elements, that are children of elements, that are children of elements, that are children of the top (document) element in the XML document. These are what you call "sub-sub children". I just hate writing looong expressions in place of short ones. So, this template matches all such elements and for every such element displays the name of its "grand-father", and its own name. To get systematic knowledge, watch a good Pluralsight XSLT course such as: pluralsight.com/courses/xslt-foundations-part1
@Rotan075, Just run the transformation applying it on the provided XML document and see that the wanted, correct result is produced. Then, please, ask new, separate questions, because the foundations of XSLT cannot be explained just in a few comments. My answer just hints how powerful XSLT is and what one can do with XSLT.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.