Reputation: 41
I have a very big xml in which a block keep repeating.Now I want only the tag names of first block.I'm poor in xsl.I tried but in vain.Please anyone help. My xml is as show below,
<catalog>
<product>
<title>GATE MCQ For Electronics & Communication Engineering</title>
<originalprice>Rs 680</originalprice>
<sellingprice>Rs 680Rs 530</sellingprice>
<discount>22% Off</discount>
<payment>Cash on delivery available</payment>
<review/>
</product>
<product>
<title>Gate Guide Computer Science / Information Technology (with CD)</title>
<originalprice>Rs 695</originalprice>
<sellingprice>Rs 695Rs 480</sellingprice>
<discount>31% Off</discount>
<payment>Cash on delivery available</payment>
<review/>
</product>
The product block keeps repeating but with different values. My xsl which I'm using now is,
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.java2s.com"
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="//*[local-name() = 'product'][1]/*">
<xsl:value-of select="name()"/>
</xsl:template>
</xsl:stylesheet>
And the output am getting is,
title
originalprice
sellingprice
discount
payment
review
Gate Guide Computer Science / Information Technology (with CD)
Rs 695
Rs 695Rs 480
31% Off
Cash on delivery available
But required output is,
title
originalprice
sellingprice
discount
payment
review
Thank you.
Upvotes: 1
Views: 251
Reputation: 243529
As simple as this:
<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="product[1]/*">
<xsl:value-of select="concat(name(), '
')"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<catalog>
<product>
<title>GATE MCQ For Electronics & Communication Engineering</title>
<originalprice>Rs 680</originalprice>
<sellingprice>Rs 680Rs 530</sellingprice>
<discount>22% Off</discount>
<payment>Cash on delivery available</payment>
<review/>
</product>
<product>
<title>Gate Guide Computer Science / Information Technology (with CD)</title>
<originalprice>Rs 695</originalprice>
<sellingprice>Rs 695Rs 480</sellingprice>
<discount>31% Off</discount>
<payment>Cash on delivery available</payment>
<review/>
</product>
</catalog>
the wanted, correct result is produced:
title
originalprice
sellingprice
discount
payment
review
Upvotes: 2
Reputation: 6615
you need to start your template from the root (by matching '/') and then limit the elements you want to have processed using 'apply-templates', like so:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.java2s.com"
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="/catalog/product[position() = 1]"/>
</xsl:template>
<xsl:template match="product">
<xsl:for-each select="./*">
<xsl:value-of select="name()"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
this will produce the desired output...
Upvotes: 2
Reputation: 100545
"//*"
is "all nodes starting from root", you probably want more restrictive XPath like "/catalog/product/*" (or similar with local-name
function if you don't want to handle namespaces properly).
Upvotes: 1