Insert element and add prefix using xslt - xslt

I need to add or insert another element and attribute <vat:IRmark Type="generic"/> after the <DefaultCurrency>. And, there is a certain group which is the <Group> element that I need to add a prefix. I almost did it, but the insertion of element didn't working. Here is my sample test file:
INPUT File:
<Data>
<Record>
<ID>123-AAA</ID>
<Date>2017-04-23</Date>
<Group>
<Hdr>
<ID>833-AAA</ID>
<DefaultCurrency>GBP</DefaultCurrency>
<Sender>truth</Sender>
</Hdr>
</Group>
</Record>
GENERATED OUTPUT:
<Data>
<Record xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:vat="http://www.govtalk.gov.uk/taxation/vat/vatdeclaration/2" schemaLocation="http://www.govtalk.gov.uk/CM/envelope http://www.govtalk.gov.uk/taxation/vat/vatdeclaration/2">
<ID>123-AAA</ID>
<Date>2017-04-23</Date>
<vat:Group>
<vat:Hdr>
<vat:ID>833-AAA</vat:ID>
<vat:DefaultCurrency>GBP</vat:DefaultCurrency>
<vat:Sender>truth</vat:Sender>
</vat:Hdr>
</vat:Group>
</Record>
EXPECTED OUTPUT:
<Data>
<Record xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:vat="http://www.govtalk.gov.uk/taxation/vat/vatdeclaration/2" schemaLocation="http://www.govtalk.gov.uk/CM/envelope http://www.govtalk.gov.uk/taxation/vat/vatdeclaration/2">
<ID>123-AAA</ID>
<Date>2017-04-23</Date>
<vat:Group>
<vat:Hdr>
<vat:ID>833-AAA</vat:ID>
<vat:DefaultCurrency>GBP</vat:DefaultCurrency>
<vat:IRmark Type="generic"/>
<vat:Sender>truth</vat:Sender>
</vat:Hdr>
</vat:Group>
</Record>
XSLT Code:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:vat="http://www.govtalk.gov.uk/taxation/vat/vatdeclaration/2">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()[boolean(normalize-space())]|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="DefaultCurrency">
<xsl:copy-of select="."/>
<vat:IRmark>
<xsl:attribute name="Type">generic</xsl:attribute>
</vat:IRmark>
</xsl:template>
<xsl:template match="*[ancestor-or-self::Group]">
<xsl:element name="vat:{local-name()}">
<xsl:copy-of select="#*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="Record">
<Record xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:vat="http://www.govtalk.gov.uk/taxation/vat/vatdeclaration/2" schemaLocation="http://www.govtalk.gov.uk/CM/envelope http://www.govtalk.gov.uk/taxation/vat/vatdeclaration/2">
<xsl:apply-templates/>
</Record>
</xsl:template>
Thank you.

This is because of template priority. The template that matches *[ancestor-or-self::Group] will match also the element DefaultCurrency. Because of the condition in the template match, the template has a higher priority (0.5, I think, compared with a priority of 0 for the template matching DefaultCurrency) and so this template will be used.
To get around this, assign a manual priority to your template that matches DefaultCurrency
<xsl:template match="DefaultCurrency" priority="1">
You can read up on conflict resolution for templates at https://www.w3.org/TR/xslt#conflict

Related

XSL to Parse and Re-order XML Nodes

I need assistance with creating a XSL stylesheet to parse data and re-order based on values within certain nodes. My original XML is being exported by a roster program in a undesirable structure which is causing issues when converting to JSON.
This is a Fire Department roster that will be converted into JSON to be processed by Station Status Boards. I'm looking to format the XML so that when converted into JSON each Station has a crew list. I've attempted to create a XSL without success. I have zero background in XSL (Fire Fighter).
Section of Original XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Data>
<Date>2019-05-07-07:00</Date>
<Headers></Headers>
<Records>
<Record>
<RscPayrollIDCh>12345678</RscPayrollIDCh>
<RscEmployeeIDCh>12345678</RscEmployeeIDCh>
<RscMasterNameCh>Smith, Mike A.</RscMasterNameCh>
<InstitutionAbrvCh>SPL</InstitutionAbrvCh>
<AgencyAbrvCh>SPFD</AgencyAbrvCh>
<RegionAbrvCh>OPS</RegionAbrvCh>
<StationAbrvCh>B19</StationAbrvCh>
<PUnitAbrvCh>BAT19</PUnitAbrvCh>
<PosJobAbrvCh>BC-S</PosJobAbrvCh>
</Record>
<Record>
<RscPayrollIDCh>12345</RscPayrollIDCh>
<RscEmployeeIDCh>12345</RscEmployeeIDCh>
<RscMasterNameCh>Smith, John A.</RscMasterNameCh>
<InstitutionAbrvCh>SPL</InstitutionAbrvCh>
<AgencyAbrvCh>SPFD</AgencyAbrvCh>
<RegionAbrvCh>OPS</RegionAbrvCh>
<StationAbrvCh>S15</StationAbrvCh>
<PUnitAbrvCh>E15</PUnitAbrvCh>
<PosJobAbrvCh>CAPT</PosJobAbrvCh>
</Record>
<Record>
<RscPayrollIDCh>123456</RscPayrollIDCh>
<RscEmployeeIDCh>123456</RscEmployeeIDCh>
<RscMasterNameCh>Smith, Bob R.</RscMasterNameCh>
<InstitutionAbrvCh>SPL</InstitutionAbrvCh>
<AgencyAbrvCh>SPFD</AgencyAbrvCh>
<RegionAbrvCh>OPS</RegionAbrvCh>
<StationAbrvCh>S15</StationAbrvCh>
<PUnitAbrvCh>E15</PUnitAbrvCh>
<PosJobAbrvCh>ENG</PosJobAbrvCh>
</Record>
</Records>
</Data>
I would like to format the XML so that it looks something like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Data>
<Date>2019-05-07-07:00</Date>
<Headers></Headers>
<Records>
<Record>
<StationAbrvCh>B19</StationAbrvCh>
<RscMasterNameCh>Smith, Mike A.</RscMasterNameCh>
</Record>
<Record>
<StationAbrvCh>S15</StationAbrvCh>
<RscMasterNameCh>Smith, John A.</RscMasterNameCh>
<RscMasterNameCh>Smith, Bob R.</RscMasterNameCh>
</Record>
</Records>
I would like my roster to list each crew member under the Station they are assigned to for the day.
If you are using XSLT 1.0, Muenchian grouping is the best approach to achieve it as below:
<?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" indent="yes" />
<xsl:key name="groups" match="/Data/Records/Record" use="StationAbrvCh" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="/Data/Records">
<xsl:copy>
<xsl:for-each select="Record[generate-id() = generate-id(key('groups', StationAbrvCh)[1])]">
<xsl:copy>
<StationAbrvCh><xsl:value-of select="StationAbrvCh" /></StationAbrvCh>
<xsl:for-each select="key('groups', StationAbrvCh)">
<RscMasterNameCh><xsl:value-of select="RscMasterNameCh" /></RscMasterNameCh>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
See demo here: https://xsltfiddle.liberty-development.net/pPzifpM
Using XSLT 2.0 it is quite easy.
In the template maching Records, you should use for-each-group
selecting Record elements and grouping them by StationAbrvCh.
Within each group you should:
Generate StationAbrvCh element, filled with the current grouping key
(also StationAbrvCh).
Run a for-each loop for the current group, copying to the output the
current RscMasterNameCh.
The script should contain also the identity template.
Below you have an example script:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Records">
<xsl:copy>
<xsl:for-each-group select="Record" group-by="StationAbrvCh">
<xsl:copy>
<StationAbrvCh><xsl:value-of select="current-grouping-key()"/></StationAbrvCh>
<xsl:for-each select="current-group()">
<xsl:sequence select="RscMasterNameCh"/>
</xsl:for-each>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy><xsl:apply-templates select="#*|node()"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
Maybe, to fully understand each detail of the above solution,
you should search the Web for description of for-each-group
and related functions (current-grouping-key() and current-group).

XSLT code to remove xml tag

I have an incoming XML like below: I need to remove the <shoeboxImage> tag from the incoming below XML.
Incoming XML Input:
<attachReceipt>
<baseMessage>
<returnCode>200</returnCode>
</baseMessage>
<payload>
<returnCode>0</returnCode>
<shoeboxItem>
<shoeboxImageCount>2</shoeboxImageCount>
<shoeboxImages>
<shoeboxImage>
<name>receiptImage.jpg</name>
</shoeboxImage>
<shoeboxImage>
<name>receiptImage.jpg</name>
</shoeboxImage>
</shoeboxImages>
</shoeboxItem>
</payload>
</attachReceipt>
Expected Output:
<attachReceipt>
<baseMessage>
<returnCode>200</returnCode>
</baseMessage>
<payload>
<returnCode>0</returnCode>
<shoeboxItem>
<shoeboxImageCount>2</shoeboxImageCount>
<shoeboxImages>
<name>receiptImage.jpg</name>
<name>receiptImage.jpg</name>
</shoeboxImages>
</shoeboxItem>
</payload>
</attachReceipt>
Need some xslt code snippet to do this.
I don't have the necessary software installed to actually test this, but this should work:
<xsl:template match="shoeboxImage">
<xsl:apply-templates select="*|text()"/>
</xsl:template>
The idea is that when a shoeboxImage element is encountered, it generates nothing for the element itself, and just continues with its children.
You need to have an identity template and a template that will remove the element shoeboxImage but will retain its descendants.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<!-- identity template -->
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<!-- template override for the element shoeboxImage -->
<xsl:template match="shoeboxImage">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

xslt: move all siblings inside the first one

I've searched through similar questions, but couldn't make any of the suggestions to work. I have the following xml I need to modify it
<XDB>
<ROOT>
<KEY><ID>12345</ID><DATE>5/10/2011</DATE></KEY>
<PERSONAL><ID>1</ID><INFO><LASTNAME>Smith</LASTNAME>...</INFO></PERSONAL>
<CONTACT><ID>1</ID><EMAIL>asmith#yahoo.com</EMAIL>...</CONTACT>
</ROOT>
<ROOT>
<KEY><ID>98765</ID><DATE>5/10/2013</DATE></KEY>
<CONTACT><ID>2</ID><EMAIL>psmithton#yahoo.com</EMAIL>...</CONTACT>
</ROOT>
...
</XDB>
And it needs to look like this:
<XDB>
<ROOT>
<KEY><ID>12345</ID><DATE>5/10/2011</DATE>
<PERSONAL><ID>1</ID><INFO><LASTNAME>Smith</LASTNAME>...</INFO></PERSONAL>
<CONTACT><ID>1</ID><EMAIL>asmith#yahoo.com</EMAIL>...</CONTACT>
</KEY>
</ROOT>
<ROOT>
<KEY><ID>98765</ID><DATE>5/10/2013</DATE>
<CONTACT><ID>2</ID><EMAIL>psmithton#yahoo.com</EMAIL>...</CONTACT>
</KEY>
</ROOT>
...
</XDB>
I need to make 2...n siblings as children of the first 'key' sibling. Essentially, i need to remove the closing < /KEY> and put it before the closing < /ROOT>. I would appreciate your help.
Thanks.
Following xslt based on Identity transform could make this job
<?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"/>
<!-- Copy everything you find... -->
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*" />
</xsl:copy>
</xsl:template>
<!-- ... but if you find first element inside ROOT ... -->
<xsl:template match="ROOT/node()[1]">
<xsl:copy>
<xsl:apply-templates select="node()|#*" />
<!-- ... copy its sibling into it ... -->
<xsl:copy-of select="following-sibling::*" />
</xsl:copy>
</xsl:template>
<!-- ignore other elements inside ROOT element since they are copied in template matching first element -->
<xsl:template match="ROOT/node()[position() > 1]" />
</xsl:stylesheet>

Adding multiple namespaces to a xml file

I have a xml file and namespaces are given in the xml file. What I need to do is to use the namespaces given in the xml file only and qualify the xml file. Below is the sample xml file.
<Ticketing xmlns="ticketing.4.0" mfAction="BOOKING">
<Reference>
<Code>190</Code>
</Reference>
<BookingID>194283532</BookingID>
<BookingCode>MCHOI190</BookingCode>
<BookingDate>2011-04-21T15:40:04.000</BookingDate>
<Persons>
<Person>
<Code>ADULT</Code>
<Count>2</Count>
</Person>
<Person>
<Code>CHILD</Code>
<Count>2</Count>
</Person>
</Persons>
<CreditCards>
<CreditCard BookingType="BOOKING">
<BookCreditCard xmlns="creditcard.3.0">
<CardCode>VS</CardCode>
<CardNumber>4444333322221111</CardNumber>
<CardExpire>2011-12-31</CardExpire>
</BookCreditCard>
</CreditCard>
</CreditCards>
</Ticketing>
I have to use the namespaces already present in the xml file and give them a prefix and qualify the xml with those namespaces. The output should be like below:-
<ticket:Ticketing xmlns:ticket="ticketing.4.0" mfAction="BOOKING">
<ticket:Reference>
<ticket:Code>190</ticket:Code>
</ticket:Reference>
<ticket:BookingID>194283532</ticket:BookingID>
<ticket:BookingCode>MCHOI190</ticket:BookingCode>
<ticket:BookingDate>2011-04-21T15:40:04.000</ticket:BookingDate>
<ticket:Persons>
<ticket:Person>
<ticket:Code>ADULT</ticket:Code>
<ticket:Count>2</ticket:Count>
</ticket:Person>
<ticket:Person>
<ticket:Code>CHILD</ticket:Code>
<ticket:Count>2</ticket:Count>
</ticket:Person>
</ticket:Persons>
<ticket:CreditCards>
<ticket:CreditCard BookingType="BOOKING">
<credit:BookCreditCard xmlns:credit="creditcard.3.0">
<credit:CardCode>VS</credit:CardCode>
<credit:CardNumber>4444333322221111</credit:CardNumber>
<credit:CardExpire>2011-12-31</credit:CardExpire>
</credit:BookCreditCard>
</ticket:CreditCard>
</ticket:CreditCards>
</ticket:Ticketing>
Can someone suggest how to implement this.
Thanks
Rudra
I'm not sure is the best way to do it. But it does the job:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="*">
<xsl:element name="ticket:{name()}" namespace="ticketing.4.0">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
<xsl:template match="BookCreditCard|BookCreditCard//*"">
<xsl:element name="credit:{name()}" namespace="creditcard.3.0">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
In XSLT 1.0 there is no guaranteed solution, because implementations are free to use any prefix in the output file that they want. However most processors do the reasonable thing, and #empo's solution will therefore usually work. In XSLT 2.0 it is guaranteed to work.
I would be inclined to use the namespace to control which template is chosen, something like this:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ticket="ticketing.4.0" xmlns:credit="creaditcard.3.0">
<xsl:output indent="yes"/>
<xsl:template match="ticket:*">
<xsl:element name="ticket:{local-name()}">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
<xsl:template match="credit:*">
<xsl:element name="credit:{local-name()}">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
A more general solution (no hardcoded prefixes and can work with any number of namespaces):
<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="#*">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="*">
<xsl:element name=
"{substring(namespace-uri(),1,6)}:{local-name()}"
namespace="{namespace-uri()}">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<Ticketing xmlns="ticketing.4.0" mfAction="BOOKING">
<Reference>
<Code>190</Code>
</Reference>
<BookingID>194283532</BookingID>
<BookingCode>MCHOI190</BookingCode>
<BookingDate>2011-04-21T15:40:04.000</BookingDate>
<Persons>
<Person>
<Code>ADULT</Code>
<Count>2</Count>
</Person>
<Person>
<Code>CHILD</Code>
<Count>2</Count>
</Person>
</Persons>
<CreditCards>
<CreditCard BookingType="BOOKING">
<BookCreditCard xmlns="creditcard.3.0">
<CardCode>VS</CardCode>
<CardNumber>4444333322221111</CardNumber>
<CardExpire>2011-12-31</CardExpire>
</BookCreditCard>
</CreditCard>
</CreditCards>
</Ticketing>
the wanted, correct result is produced:
<ticket:Ticketing xmlns:ticket="ticketing.4.0" mfAction="BOOKING">
<ticket:Reference>
<ticket:Code>190</ticket:Code>
</ticket:Reference>
<ticket:BookingID>194283532</ticket:BookingID>
<ticket:BookingCode>MCHOI190</ticket:BookingCode>
<ticket:BookingDate>2011-04-21T15:40:04.000</ticket:BookingDate>
<ticket:Persons>
<ticket:Person>
<ticket:Code>ADULT</ticket:Code>
<ticket:Count>2</ticket:Count>
</ticket:Person>
<ticket:Person>
<ticket:Code>CHILD</ticket:Code>
<ticket:Count>2</ticket:Count>
</ticket:Person>
</ticket:Persons>
<ticket:CreditCards>
<ticket:CreditCard BookingType="BOOKING">
<credit:BookCreditCard xmlns:credit="creditcard.3.0">
<credit:CardCode>VS</credit:CardCode>
<credit:CardNumber>4444333322221111</credit:CardNumber>
<credit:CardExpire>2011-12-31</credit:CardExpire>
</credit:BookCreditCard>
</ticket:CreditCard>
</ticket:CreditCards>
</ticket:Ticketing>
Do note: The first 6 characters of the namespace-uri of each element are used for the prefix of the corresponding generated name. Therefore this solution works correctly as long as the starting 6 characters of any namespace-uri of an element obey the sintactical rules for NCName.

XSLT: Add namespace to root element

I need to change namespaces in the root element as follows:
input document:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
xmlns:ns2="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
desired output:
<foo audience="external" xsi:schemaLocation="urn:isbn:1-931666-22-9
http://www.loc.gov/ead/ead.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9">
I was trying to do it as I copy over the whole document and before I give any other transformation instructions, but the following doesn't work:
<xsl:template match="* | processing-instruction() | comment()">
<xsl:copy copy-namespaces="no">
<xsl:for-each select=".">
<xsl:attribute name="audience" select="'external'"/>
<xsl:namespace name="xlink" select="'http://www.w3.org/1999/xlink'"/>
</xsl:for-each>
<xsl:copy-of select="#*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
Thanks for any advice!
XSLT 2.0 isn't necessary to solve this problem.
Here is an XSLT 1.0 solution, which works equally well as XSLT 2.0 (just change the version attribute to 2.0):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="http://www.w3.org/1999/xlink"
exclude-result-prefixes="xlink"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select=
"namespace::*
[not(name()='ns2')
and
not(name()='')
]"/>
<xsl:copy-of select=
"document('')/*/namespace::*[name()='xlink']"/>
<xsl:copy-of select="#*"/>
<xsl:attribute name="audience">external</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
When the above transformation is applied on this XML document:
<foo
xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
xmlns:ns2="http://www.w3.org/1999/xlink"
xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
the wanted result is produced:
<foo xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
audience="external"/>
You should really be using the "identity template" for this, and you should always have it on hand. Create an XSLT with that template, call it "identity.xslt", then into the current XSLT. Assume the prefix "bad" for the namespace you want to replace, and "good" for the one you want to replace it with, then all you need is a template like this (I'm at work, so forgive the formatting; I'll get back to this when I'm at home): ... If that doesn't work in XSLT 1.0, use a match expression like "*[namespace-uri() = 'urn:bad-namespace'", and follow Dimitre's instructions for creating a new element programmatically. Within , you really need to just apply-template recursively...but really, read up on the identity template.