Reputation: 449
I'm trying to transform XML from one format to another but haven't had much luck in finding resources that explain how this works too well. How can I set data inside the XML tags using a value that is inside other XML tags?
Here is the starting XML
<?xml version="1.0" encoding="utf-8"?>
<In xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="in.xsd">
<Submit ID="1234">
<Label>
<Code>300</Code>
<Source>27</Source>
</Label>
<Data>
<Number>18</Number>
<Date>2018-04-01</Date>
<IsFile>0</IsFile>
<Location></Location>
<Files>
<File>
<Name>red.pdf</Name>
<Classification>FILE</Classification>
</File>
<File>
<Name>picture.pdf</Name>
<Type>IMAGE</Type>
</File>
</Files>
</Data>
</Submit>
</In>
My current XSLT
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="In"/>
</xsl:template>
<xsl:template match="In">
<Q xmlns:tns="Q" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Source="{@source}" Notification="true">
<xsl:value-of select="Submit/Label/Source"/>
</Q>
</xsl:template>
</xsl:stylesheet>
Expected end result after using XSLT to transform the XML file.
<?xml version="1.0" encoding="utf-8"?>
<Q xmlns:tns="Q" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="scheme.xsd" Source="27" Notification="true">
<SubmitID="1234">
<Label>
<Code>300</Code>
<Source>27</Source>
</Label>
<Data>
<Number>18</Number>
<Date>2018-04-01</Date>
<IsFile>0</IsFile>
</Data>
<Files>
<File>
<Name>red.pdf</Name>
<Type>FILE</Type>
</File>
<File>
<Name>picture.pdf</Name>
<Type>IMAGE</Type>
</File>
</Files>
</Submit>
</Q>
The XSLT is incomplete and doesn't produce the expected outcome. I am still missing code to generate what goes in between.
Upvotes: 0
Views: 804
Reputation: 29022
Try the following XSLT-1.0 stylesheet:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<!-- identity template - copies all elements and its children and attributes -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="/In"> <!-- Remove the 'In' element -->
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="Submit"> <!-- Create the 'Q' element and its sub-elements -->
<Q xmlns:tns="Q" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Source="{@source}" Notification="true">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="Label" />
<xsl:apply-templates select="Data" />
<xsl:apply-templates select="Data/Files" />
</xsl:copy>
</Q>
</xsl:template>
<xsl:template match="Data"> <!-- Create the 'Data' sub-element without all of its children -->
<xsl:copy>
<xsl:copy-of select="Number"/>
<xsl:copy-of select="Date"/>
<xsl:copy-of select="IsFile"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Reputation: 449
This is returning most of what I require. Is this the correct way to do this?
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="In"/>
</xsl:template>
<xsl:template match="In">
<Q xmlns:tns="Q" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Source="{Submit/Label/Source}" Notification="true">
<xsl:value-of select="Submit/Label/Source"/>
<Label>
<Code><xsl:value-of select="Submit/Label/Code"/></Code>
<Source><xsl:value-of select="Submit/Label/Source"/></Source>
</Label>
</Q>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0