Reputation: 185
I would like to transform the JOB_NUMBER field and the ORDERPK field to an Attribute of the "order" node, please can someone show me how?
I have the following XML;
<?xml version="1.0" encoding="UTF-8"?>
<dataroot
xmlns:od="urn:schemas-microsoft-com:officedata" generated="2014-12-15T14:45:35">
<order>
<ORDERPK>2</ORDERPK>
<JOB_x0020_NUMBER>S019191-9</JOB_x0020_NUMBER>
<job_description>TESTDATA</job_description>
<order_qty>1900</order_qty>
<finishing_style>PB</finishing_style>
<depth>10</depth>
<width>8</width>
<cover_pagination>4</cover_pagination>
<text_pagination>12</text_pagination>
<delivery_commence_date>15/12/2014</delivery_commence_date>
<delivery_complete_date>15/12/2014</delivery_complete_date>
<job_site>DG</job_site>
<managing_printer>DG</managing_printer>
<is_managing_printer>TRUE</is_managing_printer>
<cust_order_ref>776031</cust_order_ref>
<cust_code>Test</cust_code>
<site_cce_name>Jamie</site_cce_name>
<site_cce_email>[email protected]</site_cce_email>
<sales_person_name>Jamie Brace</sales_person_name>
<sales_person_email>[email protected]</sales_person_email>
</order>
</dataroot>
This is what I'd like my data to look like;
<order JOB_NUMBER="S019191-9" ORDERPK="2">
<job_description>TESTDATA</job_description>
etc.
This the XSLT I have come up with so far, but in all honesty I'm not familiar with XML or XSLT at all.
<?xml version="1.0" encoding="UTF‐8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" />
<xsl:template match="/order">
<root>
<xsl:apply-templates select="order" />
</root>
</xsl:template>
<xsl:template match="order">
<order JOB_x0020_NUMBER="{@JOB_x0020_NUMBER}">
<xsl:value-of select="order" />
</order>
</xsl:template>
</xsl:stylesheet>
Upvotes: 4
Views: 55
Reputation: 22647
You were not far off. Start with an identity template that just copies everything to the output tree. Then, add more specific templates for all the exceptions you'd like to define to this basic, indiscriminate copying process.
The first template matches order
and outputs a new order
element with two new attributes. Their values are retrieved with attribute value templates. But then, the two elements that are now represented as attributes should not appear in the output. Therefore, a second template matches them and simply does nothing.
It is not clear from your question whether you'd like to leave all the rest of the child elements of order
intact, but I assume it is what you want.
Stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="order">
<order JOB_NUMBER="{JOB_x0020_NUMBER}" ORDERPK="{ORDERPK}">
<xsl:apply-templates/>
</order>
</xsl:template>
<xsl:template match="JOB_x0020_NUMBER | ORDERPK"/>
</xsl:stylesheet>
XML Output
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2014-12-15T14:45:35">
<order JOB_NUMBER="S019191-9" ORDERPK="2">
<job_description>TESTDATA</job_description>
<order_qty>1900</order_qty>
<finishing_style>PB</finishing_style>
<depth>10</depth>
<width>8</width>
<cover_pagination>4</cover_pagination>
<text_pagination>12</text_pagination>
<delivery_commence_date>15/12/2014</delivery_commence_date>
<delivery_complete_date>15/12/2014</delivery_complete_date>
<job_site>DG</job_site>
<managing_printer>DG</managing_printer>
<is_managing_printer>TRUE</is_managing_printer>
<cust_order_ref>776031</cust_order_ref>
<cust_code>Test</cust_code>
<site_cce_name>Jamie</site_cce_name>
<site_cce_email>[email protected]</site_cce_email>
<sales_person_name>Jamie Brace</sales_person_name>
<sales_person_email>[email protected]</sales_person_email>
</order>
</dataroot>
By the way, in your XML, there is a namespace declaration that is never used:
xmlns:od="urn:schemas-microsoft-com:officedata"
You might want to exclude it from the result. If you can use XSLT 2.0, you could use copy-namespaces="no"
for that. In XSLT 1.0, you'd have to mimic copy-namespaces.
Upvotes: 1