tags:

views:

392

answers:

2

I have an XML document, and I want to print the tag names and values (of leaf nodes) of all tags in the document.

For example, for the XML:

<library>
  <bookrack>
    <book>
      <name>Book1</name>
      <price>$10</price>
    </book>
    <book>
      <name>Book2</name>
      <price>$15</price>
    </book>
  </bookrack>
</library>

The output should be something like:

library=
bookrack=
book=
name=Book1
price=$10
book=
name=Book2
price=$15

Help please!

A: 

if you can parse the xml with xslt then it is quite simple (output can be changed to text just used html to be able to view the result easily)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
   <xsl:output method="html" encoding="utf-8" />
   <xsl:template match="/">
      <xsl:for-each select="./*">
         <xsl:call-template name="list" />
      </xsl:for-each>
   </xsl:template>
   <xsl:template match="*" name="list">
      <xsl:value-of select="local-name(.)" /> = <xsl:value-of select="text()" /><br />
      <xsl:for-each select="./*">
         <xsl:call-template name="list" />
      </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

Returns:

library = 
bookrack = 
book = 
name = Book1
price = $10
book = 
name = Book2
price = $15
Josh
Thanks for your answer!Let me see if I can use this instead of a Java program.. :)
Phanindra K
+1  A: 

Minimalistic XSLT 1.0 approach:

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

  <xsl:output method="text" />

  <xsl:template match="*">
    <xsl:value-of select="name()" />
    <xsl:text>=</xsl:text>
    <xsl:value-of select="normalize-space(text())" />
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates />
  </xsl:template>

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

</xsl:stylesheet>

gives:

library=
bookrack=
book=
name=Book1
price=$10
book=
name=Book2
price=$15

This alternative template would treat the node values better:

<xsl:template match="*">
  <xsl:value-of select="name()" />
  <xsl:text>=</xsl:text>
  <xsl:if test="normalize-space(text()) != ''">
    <xsl:value-of select="text()" />
  </xsl:if>
  <xsl:text>&#10;</xsl:text>
  <xsl:apply-templates />
</xsl:template>

The output is the same as before, but spacing within node values would be retained.

Tomalak