Jamie Brace
Jamie Brace

Reputation: 185

How do I use a namespace declaration properly in XSLT?

I'm trying to declare a namespace so all of the elements in my XML have a tag "tg:" before the name of each element. However it doesn't appear to be working and I'm not sure why.

Here is my input XML;

<?xml version="1.0"?>
<orders>
  <dataroot generated="2015-01-09T11:57:36" xmlns:od="urn:schemas-microsoft-com:officedata">
    <order job_id="S026500-1" site_code="DG" replace="true">
    <job_description>TESTING</job_description>
    <order_qty>20000</order_qty>
    <finishing_style>PB</finishing_style>
    <depth>10</depth>
    <width>8</width>
    <cover_pagination>4</cover_pagination>
    <text_pagination>24</text_pagination>
    <delivery_commence_date>19/12/2014</delivery_commence_date>
    <delivery_complete_date>19/12/2014</delivery_complete_date>
    <job_site>DG</job_site>
    <managing_printer>DG</managing_printer>
    <is_managing_printer>True</is_managing_printer>
       <master_version>
          <version_code>COMM</version_code>
          <version_common>true</version_common>
          <version_finished>false</version_finished>
          <version_description>common</version_description>
          <version_nett_qty>20000</version_nett_qty>
          <version_special_qty>0</version_special_qty>
       </master_version>
    </order>
  </dataroot>
</orders>

This is what I'd like my output to look like;

<?xml version="1.0"?>
    <tg:orders>
        <tg:order job_id="S026500-1" site_code="DG" replace="true">
        <tg:job_description>TESTING</job_description>
        <tg:order_qty>20000</order_qty>
        <tg:finishing_style>PB</finishing_style>
        <tg:depth>10</depth>
        <tg:width>8</width>
        <tg:cover_pagination>4</cover_pagination>
        <tg:text_pagination>24</text_pagination>
        <tg:delivery_commence_date>19/12/2014</delivery_commence_date>
        <tg:delivery_complete_date>19/12/2014</delivery_complete_date>
        <tg:job_site>DG</job_site>
        <tg:managing_printer>DG</managing_printer>
        <tg:is_managing_printer>True</is_managing_printer>
           <tg:master_version>
              <tg:version_code>COMM</version_code>
              <tg:version_common>true</version_common>
              <tg:version_finished>false</version_finished>
              <tg:version_description>common</version_description>
              <tg:version_nett_qty>20000</version_nett_qty>
              <tg:version_special_qty>0</version_special_qty>
           </tg:master_version>
        </tg:order>
    </tg:orders>

This is my XSLT;

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/*[local-name()='orders']">
        <orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tg="http://www.technique-group.com" xsi:schemaLocation="http://www.technique-group.com/schemas TGScheduleImport_v1.4.xsd" tg:version="1.2">
            <xsl:copy-of select="node()|@*"/>
        </orders>
     </xsl:template>
</xsl:stylesheet>

Please can someone explain to me what I'm doing wrong? I would also like to remove the dataroot element, but that can come at a later date.

Upvotes: 0

Views: 70

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167401

Use

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:tg="http://www.technique-group.com"
    version="1.0">

<xsl:template match="*">
  <xsl:element name="tg:{local-name()}" namespace="http://www.technique-group.com">
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

<xsl:template match="dataroot">
  <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

to make sure all elements in the input are transformed to the new namespace, with the exception of dataroot, which is stripped.

Upvotes: 2

Related Questions