Reputation: 173
I am trying to transform XML, I have multiple and different input. I tried many solutions like Split specific element attribute into multiple rows based on delimiter but in my case I have different element with different attribute. Any suggestions please?
Input:
<ROOT>
<Data X="1233" Y="1:30:57" Z="abcd"/>
<Info T="1:30:57" F="xyz" H="1234" "/>
Excepted Output:
<ROOT>
<Data X="1233"/>
<Data Y="1:30:57"/>
<Data Z="abcd"/>
<Info T="1:30:57 />
<Info F="xyz" />
<Info H="1234"/>
Upvotes: 0
Views: 55
Reputation: 29022
A solution to your problem is the following stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/ROOT">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="Data | Info">
<xsl:variable name="nod" select="local-name()" />
<xsl:for-each select="@*">
<xsl:element name="{$nod}">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
The output is:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<Data X="1233"/>
<Data Y="1:30:57"/>
<Data Z="abcd"/>
<Info T="1:30:57"/>
<Info F="xyz"/>
<Info H="1234"/>
</ROOT>
Upvotes: 2
Reputation: 527
If you format your input properly
<document>
<ROOT>
<Data X="1233" Y="1:30:57" Z="abcd"/>
<Info T="1:30:57" F="xyz" H="1234"/>
</ROOT>
</document>
This should do it
<xsl:template match="Data | Info">
<xsl:for-each select="./@*">
<xsl:element name="{name(./parent::node())}">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</xsl:template>
Upvotes: 0
Reputation: 527
Your data is not actually well formed, meaning your attributes are not formatted properly.
<ROOT>
<Data "X=1233,Y=1:30:57,Z=abcd"/>
<Info " T=1:30:57,F=xyz,H=1234 "/>
</ROOT>
Should really be
<ROOT>
<Data X="1233" Y="1:30:57" Z="abcd"/>
<Info T="1:30:57" F="xyz" H="1234"/>
</ROOT>
If you must work with what you've got, you might be able to do something with xsl:analyze-string, but I'm dubious about that because the data is not well-formed XML.I don't think you'll be able to parse the attributes as they are.
Upvotes: 0