Reputation: 1
I'm trying to get specific XML from existing one. Could you help please?
Source XML:
<?xml version="1.0" encoding="utf-8"?>
<row>
<column name="testName">Test 1</column>
<column name="Tests">
<XmlDoc xmlns="Customers servers">
<Tests>
<Test>
<cuFirst>Hardware</cuFirst>
<cuLast>Server 1</cuLast>
</Test>
<Test>
<cuFirst>Hardware</cuFirst>
<cuLast>Server 2</cuLast>
</Test>
</Tests>
</XmlDoc>
</column>
<column name="Company">Some Company</column>
<column name="Company address" />
<column name="Company URL" />
<column name="Company Alias">Company Alias</column>
</row>
Current XSLT (not working as expected); I did try different things, but nothing; I will continue trying, but if you have any idea how to help, please do.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="no" />
<xsl:template match="/">
<Tests>
<xsl:for-each select="//column[@name='Tests']">
<ci>
<xsl:value-of select="//column[@name='Tests']/XmlDoc/Tests/Test//cuLast" disable-output-escaping="no" />
</ci>
</xsl:for-each>
<Test>
<xsl:value-of select="//column[@name='testName']" disable-output-escaping="no" />
</Test>
</Tests>
</xsl:template>
</xsl:stylesheet>
Desired Output XML
<Tests>
<Test>
<cuLast>Test 1</cuLast>
</Test>
<Test>
<cuLast>Server 1</cuLast>
</Test>
<Test>
<cuLast>Server 2</cuLast>
</Test>
</Tests>
Upvotes: 0
Views: 200
Reputation: 117102
First thing: the XmlDoc
element and all its descendants live in a namespace of their own; you must declare this namespace in your stylesheet, assign it a prefix and use that prefix when addressing these nodes.
Also, in XSLT it pays to be explicit: avoid the // designation if you know the exact path.
Try the following stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cs="Customers servers"
exclude-result-prefixes="cs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<Tests>
<Test><xsl:value-of select="row/column[@name='testName']"/></Test>
<xsl:for-each select="row/column[@name='Tests']/cs:XmlDoc/cs:Tests/cs:Test">
<ci>
<xsl:value-of select="cs:cuLast" />
</ci>
</xsl:for-each>
</Tests>
</xsl:template>
</xsl:stylesheet>
When applied to your input, the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<Tests>
<Test>Test 1</Test>
<ci>Server 1</ci>
<ci>Server 2</ci>
</Tests>
Note also that "Customers servers"
is not a valid URI and therefore not a good choice for a namespace. Not sure if you have any control over that, though.
Upvotes: 0