Reputation: 202
I wish to translate an XML file so that the subheaders 'Subheader1' and 'Subheader2' are removed so that a program I have can read the XML data and identify the information under 'Lines/Line'.
In this case the best way to achieve this would be to remove the subheaders and keep all the elements under a single header.
I have made attempts to achieve the problem that I am having. But, the XSLT that I have made is just being ignored. So far I have achieved just exporting the element data. But the element headers are ignored. Or, in this case, the XSLT just exports the exact same format. I just don't understand why this is happening.
XML Input
<Header xmlns="urn:stuff:xml:ns:neo">
<ID>1</ID>
<Department>350</Department>
<Date>2019-03-07T14:38:00</Date>
<Order_Number>12345</Order_Number>
<Comment/>
<Status>Picking</Status>
<Subheader1>
<Subheader2>
<Product>12510101</Product>
<Quantity>1</Quantity>
<Comment_Line/>
<Location>R11</Location>
</Subheader2>
</Subheader1>
</Header>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="urn:stuff:xml:ns:neo">
<xsl:output method="xml"
omit-xml-declaration="yes"
indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="Subheader1" />
<xsl:template match="Subheader2" />
</xsl:stylesheet>
XML Output
<Header xmlns="urn:stuff:xml:ns:neo">
<ID>1</ID>
<Department>350</Department>
<Date>2019-03-07T14:38:00</Date>
<Order_Number>12345</Order_Number>
<Comment/>
<Status>Picking</Status>
<Product>12510101</Product>
<Quantity>1</Quantity>
<Comment_Line/>
<Location>R11</Location>
</Header>
My Current Output
1
350
360
361
2019-03-07T14:38:00
615619
Active
1
12510101
50153061
23663
Active
RM STD
I'm expecting the XML output that I have added above. Any help with this including what needs to be done and why would be appreciated. Been trying to fix this for some time and just at a point where I cannot understand why this is occurring.
Upvotes: 1
Views: 1381
Reputation: 111521
General reasons XSLT might be "ignored:"
The input XML is in one or more namespaces, explicitly or by default, and your XSLT is matching against elements in no namespaces. See the XSLT below for how to match against namespaced elements.
There are typos or case disagreement between element names in the input XML and the XSLT.
None of the provided XSLT templates match, and only the built-in template rules remain to perform the transformation.
Side note: Your current output isn't really what the posted XSLT would generated for the posted XML input file. It would copy the input XSLT to the output XSLT per the identity transform, and your two Line
and Lines
templates would have no effect because there are no Line
or Lines
elements in your input XML.
Your specific case: You can unwrap the contents of the Subheader1
and Subheader2
elements via the following XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:neo="urn:stuff:xml:ns:neo">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="neo:Subheader1 | neo:Subheader2">
<xsl:apply-templates select="node() | @*"/>
</xsl:template>
</xsl:stylesheet>
<Header xmlns="urn:stuff:xml:ns:neo">
<ID>1</ID>
<Department>350</Department>
<Date>2019-03-07T14:38:00</Date>
<Order_Number>12345</Order_Number>
<Comment/>
<Status>Picking</Status>
<Product>12510101</Product>
<Quantity>1</Quantity>
<Comment_Line/>
<Location>R11</Location>
</Header>
You can eliminate the extra whitespace via
<xsl:strip-space elements="neo:Subheader1 neo:Subheader2"/>
added to xsl:stylesheet
, or you might want to only copy the element (*
) children of those two elements rather than all children node()
s:
<xsl:template match="neo:Subheader1 | neo:Subheader2">
<xsl:apply-templates select="* | @*"/>
</xsl:template>
Note that | @*
isn't really needed here but could help if your actual case has attributes. Similarly, note that you can add back processing-instruction()|comment()
if such children types are desired after changing node()
to *
.
Upvotes: 3