Generic XSLT transform to manipulate similar XML data -
we have tool producing unwanted xml element , using xslt translate required format.
we writing different xslt every xml generated file. e.g. 1 customers xml, 1 orders xml , on.
below couple of xml data files produced tool , actual output expected
customers
tool-generated xml
<message> <data> <customerarray> <customer> <x> <name>john</name> <id>100</id> <roles> <role> <x>manager</x> <x>architect</x> </role> </roles> </x> <x> <name>doe</name> <id>102</id> <roles> <role> <x>supervisor</x> <x>admin</x> </role> </roles> </x> </customer> </customerarray> </data> </message>
required xml data
<message> <data> <customerarray> <customer> <name>john</name> <id>100</id> <roles> <role>manager</role> <role>architect</role> </roles> </customer> <customer> <name>doe</name> <id>102</id> <roles> <role>supervisor</role> <role>admin</role> </roles> </customer> </customerarray> </data> </message>
orders
tool-generated xml
<message> <orders> <order> <x> <ordernumber>o123</ordernumber> <customerid>c100</customerid> <quantity>100</quantity> <unitprice>10.0</unitprice> </x> <x> <ordernumber>o456</ordernumber> <customerid>c107</customerid> <quantity>100</quantity> <unitprice>5.0</unitprice> </x> </order> </orders> </message>
required xml data
<message> <orders> <order> <ordernumber>o123</ordernumber> <customerid>c100</customerid> <quantity>100</quantity> <unitprice>10.0</unitprice> </order> <order> <ordernumber>o456</ordernumber> <customerid>c107</customerid> <quantity>100</quantity> <unitprice>5.0</unitprice> </order> </orders> </message>
the unwanted element x
can come @ level.
is possible write generic xslt transform achieve result across xml input? instance, x
found, replace parent tag , delete parent tag.
here simpler/shorter solution, handles correctly case when x
can have non x
sibling elements:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="*[x]"><xsl:apply-templates/></xsl:template> <xsl:template match="x"> <xsl:element name="{name(..)}"> <xsl:apply-templates select="node()|@*"/> </xsl:element> </xsl:template> </xsl:stylesheet>
when transformation applied following xml document (the first of provided ones, 1 non-x
sibling added x
elements:
<message> <data> <customerarray> <customer> <x> <name>john</name> <id>100</id> <roles> <role> <x>manager</x> <x>architect</x> </role> </roles> </x> <somethingelse/> <x> <name>doe</name> <id>102</id> <roles> <role> <x>supervisor</x> <x>admin</x> </role> </roles> </x> </customer> </customerarray> </data> </message>
the wanted, correct result produced:
<message> <data> <customerarray> <customer> <name>john</name> <id>100</id> <roles> <role>manager</role> <role>architect</role> </roles> </customer> <somethingelse/> <customer> <name>doe</name> <id>102</id> <roles> <role>supervisor</role> <role>admin</role> </roles> </customer> </customerarray> </data> </message>
do note solution borodin loses somethingelse
element.
Comments
Post a Comment