I want to transform a XML document with XSLT. A node and its childern matched by name and attribute should be nested/moved into a new node.
Transform from
<v:data name="Custom">
<valueA>bla</valueA>
<valueB>bla</valueB>
<valueC>
<valueA>bla</valueA>
<valueB>bla</valueB>
</valueC>
</v:data>
to
<v:container type="static">
<!-- origin node -->
<v:data name="Custom">
<valueA>bla</valueA>
<valueB>bla</valueB>
<valueC>
<valueA>bla</valueA>
<valueB>bla</valueB>
</valueC>
</v:data>
</v:container>
But my XSLT doesn't work well. Do you have a hint for me, what is wrong with the XSLT file?
Thank you very much
Andreas
My XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:v="http://acme.com/schema.xsd"
xmlns:d="http://acme.com/data.xsd"
>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() |@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="v:data/@name[.='Custom']">
<xsl:element name="v:container">
<xsl:attribute name="type">static</xsl:attribute>
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The output:
<?xml version="1.0" encoding="UTF-8"?>
<datamodel xmlns:v="http://acme.com/schema.xsd" xmlns:d="http://acme.com/data.xsd">
<v:data> <!-- should be under v:container -->
<v:container type="static" name="Custom"/> <!-- attribute name should be by v:data -->
<valueA>bla</valueA> <!-- children should be under v:data -->
<valueB>bla</valueB>
<valueC>
<valueA>bla</valueA>
<valueB>bla</valueB>
</valueC>
</v:data>
<v:data name="Default"> <!-- okay: is untouched -->
<valueA>bla</valueA>
<valueB>bla</valueB>
<valueC>
<valueA>bla</valueA>
<valueB>bla</valueB>
</valueC>
</v:data>
</datamodel>
My source XML file
<?xml version="1.0" encoding="UTF-8"?>
<datamodel
xmlns:v="http://acme.com/schema.xsd"
xmlns:d="http://acme.com/data.xsd"
>
<v:data name="Custom">
<valueA>bla</valueA>
<valueB>bla</valueB>
<valueC>
<valueA>bla</valueA>
<valueB>bla</valueB>
</valueC>
</v:data>
<v:data name="Default">
<valueA>bla</valueA>
<valueB>bla</valueB>
<valueC>
<valueA>bla</valueA>
<valueB>bla</valueB>
</valueC>
</v:data>
</datamodel>
What I expected at the transformed output I want to nested v:data node and its children into a new node. But only v:data nodes with the attribute name="Custon". After transformation the XML document should look like this
<?xml version="1.0" encoding="UTF-8"?>
<datamodel
xmlns:v="http://acme.com/schema.xsd"
xmlns:d="http://acme.com/data.xsd"
>
<v:container type="static"> <!-- changed -->
<v:data name="Custom">
<valueA>bla</valueA>
<valueB>bla</valueB>
<valueC>
<valueA>bla</valueA>
<valueB>bla</valueB>
</valueC>
</v:data>
</v:container>
<v:data name="Default"> <!-- unchanged -->
<valueA>bla</valueA>
<valueB>bla</valueB>
<valueC>
<valueA>bla</valueA>
<valueB>bla</valueB>
</valueC>
</v:data>
</datamodel>
Match without attribute If I remove the attribute selector from the template in the XSLT. It will be work - but now very node is transformed.
<?xml version="1.0" encoding="UTF-8"?>
<datamodel xmlns:v="http://acme.com/schema.xsd" xmlns:d="http://acme.com/data.xsd">
<v:container type="static"> <!-- as I expected -->
<v:data name="Custom">
<valueA>bla</valueA>
<valueB>bla</valueB>
<valueC>
<valueA>bla</valueA>
<valueB>bla</valueB>
</valueC>
</v:data>
</v:container>
<v:container type="static"> <!-- but all v:data nodes are moved -->
<v:data name="Default">
<valueA>bla</valueA>
<valueB>bla</valueB>
<valueC>
<valueA>bla</valueA>
<valueB>bla</valueB>
</valueC>
</v:data>
</v:container>
</datamodel>