XSLT1.0 copy all nodes and add a few similar nodes - xslt

I have xml and I would like to add a few elements, but without affecting the other elements that are already there. The order of the elements is not important. But one of the new elements is not being added, how to fix it?
Input XML
<?xml version="1.0" encoding="utf-8"?>
<root>
<InterchangeHeader>InterchangeHeader</InterchangeHeader>
<SG0>
<UNH>UNH</UNH>
<BGM>BGM</BGM>
<DTM>DTM</DTM>
<SG26>
<LIN>
<E1082>000010</E1082>
<C212>
<E7143>SRV</E7143>
</C212>
</LIN>
<PIA>
<E4347>1</E4347>
<C212>
<E7140>000010</E7140>
<E7143>IN</E7143>
</C212>
</PIA>
<QTY>
<C186>
<E6063>21</E6063>
<E6060>2100.000</E6060>
<E6411>EA</E6411>
</C186>
</QTY>
<QTY>
<C186>
<E6063>170</E6063>
<E6060>2100.000</E6060>
<E6411>EA</E6411>
</C186>
</QTY>
</SG26>
<SG26>
<LIN>
<E1082>000020</E1082>
<C212>
<E7143>SRV</E7143>
</C212>
</LIN>
<PIA>
<E4347>1</E4347>
<C212>
<E7140>000020</E7140>
<E7143>IN</E7143>
</C212>
</PIA>
<QTY>
<C186>
<E6063>21</E6063>
<E6060>2100.000</E6060>
<E6411>EA</E6411>
</C186>
</QTY>
<QTY>
<C186>
<E6063>170</E6063>
<E6060>0.000</E6060>
<E6411>EA</E6411>
</C186>
</QTY>
</SG26>
<SG26>
<LIN>
<E1082>000030</E1082>
<C212>
<E7143>SRV</E7143>
</C212>
</LIN>
<PIA>
<E4347>1</E4347>
<C212>
<E7140>000030</E7140>
<E7143>IN</E7143>
</C212>
</PIA>
<QTY>
<C186>
<E6063>21</E6063>
<E6060>2100.000</E6060>
<E6411>EA</E6411>
</C186>
</QTY>
<QTY>
<C186>
<E6063>170</E6063>
<E6060>1900.000</E6060>
<E6411>EA</E6411>
</C186>
</QTY>
</SG26>
<UNS>
<E0081>S</E0081>
</UNS>
</SG0>
<InterchangeTrailer>InterchangeTrailer</InterchangeTrailer>
</root>
MY XSLT In the first part, I copy everything, and then I try to change
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt" xmlns:ext="urn:ext" exclude-result-prefixes="ext msxml">
<xsl:output method="xml" indent="yes" encoding="utf-8"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SG26[not(QTY/C186/E6063=59)]">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
<QTY>
<C186>
<E6063>59</E6063>
<E6060>
<xsl:value-of select="'status'"/>
</E6060>
<E6411>
<xsl:value-of select="'status'"/>
</E6411>
</C186>
</QTY>
</xsl:copy>
</xsl:template>
<xsl:template match="SG26[not(QTY/C186/E6063=60)]">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
<QTY>
<C186>
<E6063>60</E6063>
<E6060>
<xsl:value-of select="'status2'"/>
</E6060>
<E6411>
<xsl:value-of select="'status2'"/>
</E6411>
</C186>
</QTY>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
I would like to add a few elements, but without affecting the other elements that are already there. The order of the elements is not important. But one of the new elements is deleted, how can I fix it?

Perhaps you can solve it as follows:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt" xmlns:ext="urn:ext" exclude-result-prefixes="ext msxml">
<xsl:param name="elements-to-add-rtf">
<QTY>
<C186>
<E6063>59</E6063>
<E6060>status</E6060>
<E6411>status</E6411>
</C186>
</QTY>
<QTY>
<C186>
<E6063>60</E6063>
<E6060>status2</E6060>
<E6411>status2</E6411>
</C186>
</QTY>
</xsl:param>
<xsl:variable name="elements-to-add" select="msxml:node-set($elements-to-add-rtf)"/>
<xsl:output method="xml" indent="yes" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SG26">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
<xsl:apply-templates select="$elements-to-add/QTY[not(C186/E6063 = current()/QTY/C186/E6063)]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Note that the XSLT 1 specific use of the namespace for the extension function node-set is processor dependent, as your code declared the prefix and namespace that works with Microsoft processors I assumed you are working with one of them and used that prefix.

Related

Using multiple namespaces inside xml

I have an xml which contains two namespaces. I need one to be changed as ns0 and the other as ns1.
The namespace http://www.nrf-arts.org/IXRetail/namespace/ needs to be added as ns0 and http://www.datavantagecorp.com/xstore/ as ns1. Basiscally the second namespace is a reference namespace.
I have tried the below code. But it did not help me.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://sample.com/s"
xmlns:ns0="http://www.nrf-arts.org/IXRetail/namespace/" xmlns:ns1="http://www.datavantagecorp.com/xstore/"
xmlns:dtv="http://www.datavantagecorp.com/xstore/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()[not(self::dtv)]">
<xsl:element name="ns0:{local-name()}">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="dtv:*">
<xsl:element name="ns1:{local-name()}">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The structure I have
<?xml version="1.0" encoding="UTF-8"?>
<Sales_Posting>
<row>
<POSLog xmlns="http://www.nrf-arts.org/IXRetail/namespace/"
xmlns:dtv="http://www.datavantagecorp.com/xstore/"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ POSLog.xsd">
<Transaction CancelFlag="true"
OfflineFlag="false"
TrainingModeFlag="false"
dtv:AppVersion="17.0.0.0.716 - 0.0.0 - 0.0"
dtv:TransactionType="RETAIL_SALE">
<dtv:OrganizationID>1</dtv:OrganizationID>
<RetailStoreID>103</RetailStoreID>
<WorkstationID>3</WorkstationID>
<TillID>47957</TillID>
<SequenceNumber>1396</SequenceNumber>
<BusinessDayDate>2019-05-08</BusinessDayDate>
<BeginDateTime>2019-05-08T14:51:48.731</BeginDateTime>
<EndDateTime>2019-05-23T23:37:41.209</EndDateTime>
<OperatorID>47957</OperatorID>
<CurrencyCode>INR</CurrencyCode>
<RollOverCode>0</RollOverCode>
<MMSTxnType>87</MMSTxnType>
Expected output:-
<?xml version="1.0" encoding="UTF-8"?>
<ns0:Sales_Posting xmlns:ns0="http://www.nrf-arts.org/IXRetail/namespace/">
<ns0:row>
<ns0:POSLog>
<ns0:Transaction CancelFlag="false" TrainingModeFlag="false" OfflineFlag="" ns1:TransactionType="" ns1:AppVersion="17.0.0.0.716 - 0.0.0 - 0.0" ns1:crossChannelReturn="" ns1:InventoryDocumentSubType="" ns1:InventoryDocumentType="" xmlns:ns1="http://www.datavantagecorp.com/xstore/">
<ns1:OrganizationID xmlns:ns1="http://www.datavantagecorp.com/xstore/">1</ns1:OrganizationID>
<ns0:RetailStoreID>103</ns0:RetailStoreID>
<ns0:WorkstationID>3</ns0:WorkstationID>
<ns0:TillID>47957</ns0:TillID>
<ns1:CashDrawerID xmlns:ns1="http://www.datavantagecorp.com/xstore/"/>
<ns0:SequenceNumber/>
<ns0:BusinessDayDate/>
<ns0:BeginDateTime/>
<ns0:EndDateTime/>
<ns0:OperatorID/>
<ns0:CurrencyCode/>
<ns1:FiscalNumber xmlns:ns1="http://www.datavantagecorp.com/xstore/"/>
<ns1:DeviceId xmlns:ns1="http://www.datavantagecorp.com/xstore/"/>
<ns1:FiscalSessionNumber xmlns:ns1="http://www.datavantagecorp.com/xstore/"/>
<ns1:PosTransactionProperties xmlns:ns1="http://www.datavantagecorp.com/xstore/"/>
<ns0:RollOverCode/>
<ns0:MMSTxnType/>
<ns0:SuspendReasonCode/>
<ns0:MMSReasonType/>
<ns0:MEPNumber/>
<ns0:TransactionComment/>
<ns0:TransNumberReturnWOReceipt/>
Ignoring the fact that the namespace prefix is arbitrary, and any XML parser shouldn't care what they are (as long as the actual namespace is as expected), the below should help you:
Stylesheet
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://www.nrf-arts.org/IXRetail/namespace/"
xmlns:ns1="http://www.datavantagecorp.com/xstore/"
xmlns:dtv="http://www.datavantagecorp.com/xstore/">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="#*">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="dtv:*">
<xsl:element name="ns1:{local-name(.)}">
<xsl:value-of select="text()" />
<xsl:apply-templates select="#* | node()" />
</xsl:element>
</xsl:template>
<xsl:template match="node()[local-name() != '']">
<xsl:element name="ns0:{local-name()}">
<xsl:value-of select="text()" />
<xsl:apply-templates select="#* | node()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Three templates:
Match any attributes and just copy them across.
Match anything in the dtv namespace, rename the prefix to ns1 and copy the text content and recursively map any children
Match any other nodes and apply the http://www.nrf-arts.org/IXRetail/namespace/ namespace with ns0 prefix, copy the text content and recursively map any children
I think your input was truncated in the question, but it seemed to do the trick.
Input
<?xml version="1.0" encoding="UTF-8"?>
<Sales_Posting>
<row>
<POSLog xmlns="http://www.nrf-arts.org/IXRetail/namespace/"
xmlns:dtv="http://www.datavantagecorp.com/xstore/"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ POSLog.xsd">
<Transaction CancelFlag="true" OfflineFlag="false"
TrainingModeFlag="false" dtv:AppVersion="17.0.0.0.716 - 0.0.0 - 0.0"
dtv:TransactionType="RETAIL_SALE">
<dtv:OrganizationID>1</dtv:OrganizationID>
<RetailStoreID>103</RetailStoreID>
<WorkstationID>3</WorkstationID>
<TillID>47957</TillID>
<SequenceNumber>1396</SequenceNumber>
<BusinessDayDate>2019-05-08</BusinessDayDate>
<BeginDateTime>2019-05-08T14:51:48.731</BeginDateTime>
<EndDateTime>2019-05-23T23:37:41.209</EndDateTime>
<OperatorID>47957</OperatorID>
<CurrencyCode>INR</CurrencyCode>
<RollOverCode>0</RollOverCode>
<MMSTxnType>87</MMSTxnType>
</Transaction>
</POSLog>
</row>
</Sales_Posting>
Output
<?xml version="1.0" encoding="UTF-8"?>
<ns0:Sales_Posting
xmlns:ns0="http://www.nrf-arts.org/IXRetail/namespace/">
<ns0:row>
<ns0:POSLog
xs:schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ POSLog.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<ns0:Transaction CancelFlag="true"
OfflineFlag="false" TrainingModeFlag="false"
dtv:AppVersion="17.0.0.0.716 - 0.0.0 - 0.0"
xmlns:dtv="http://www.datavantagecorp.com/xstore/"
dtv:TransactionType="RETAIL_SALE">
<ns1:OrganizationID
xmlns:ns1="http://www.datavantagecorp.com/xstore/">1</ns1:OrganizationID>
<ns0:RetailStoreID>103</ns0:RetailStoreID>
<ns0:WorkstationID>3</ns0:WorkstationID>
<ns0:TillID>47957</ns0:TillID>
<ns0:SequenceNumber>1396</ns0:SequenceNumber>
<ns0:BusinessDayDate>2019-05-08</ns0:BusinessDayDate>
<ns0:BeginDateTime>2019-05-08T14:51:48.731</ns0:BeginDateTime>
<ns0:EndDateTime>2019-05-23T23:37:41.209</ns0:EndDateTime>
<ns0:OperatorID>47957</ns0:OperatorID>
<ns0:CurrencyCode>INR</ns0:CurrencyCode>
<ns0:RollOverCode>0</ns0:RollOverCode>
<ns0:MMSTxnType>87</ns0:MMSTxnType>
</ns0:Transaction>
</ns0:POSLog>
</ns0:row>
</ns0:Sales_Posting>

XSLT copy without segment name

I have the following XML:
<segment>
<personal_information>
<birth_name>xxx</birth_name>
<created_by>yyy</created_by>
<created_on_timestamp>2018-08-06T06:41:07.000Z</created_on_timestamp>
</personal_information>
<segment>
I want to copy the entire personal_information segment with all elements and sub-segments while adding a new field. I tried this with:
<segment>
<personal_information>
<action>DELETE</action>
<xsl:copy>
<xsl:apply-templates select="child::node()"/>
</xsl:copy>
</personal_information>
</segment>
But this results in the following:
<segment>
<personal_information>
<action>DELETE</action>
<personal_information>
<birth_name>xxx</birth_name>
<created_by>yyy</created_by>
<created_on_timestamp>2018-08-06T06:41:07.000Z</created_on_timestamp>
</personal_information>
</personal_information>
</segment>
Would would be the XSLT code to achieve this as a result:
<segment>
<personal_information>
<action>DELETE</action>
<birth_name>xxx</birth_name>
<created_by>yyy</created_by>
<created_on_timestamp>2018-08-06T06:41:07.000Z</created_on_timestamp>
</personal_information>
</segment>
I do not want to copy all fields one by one.
Instead of using <xsl:copy>, use <xsl:copy-of>, which accepts an XPath expression for the nodes to be included in the copy; in this case only the inner childnodes.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="segment">
<segment>
<personal_information>
<action>DELETE</action>
<xsl:copy-of select="personal_information/*" />
</personal_information>
</segment>
</xsl:template>
</xsl:stylesheet>
You need a identity template and one personal_information with adding one action element:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="personal_information">
<xsl:copy>
<action>DELETE</action>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Updated as per new requirement :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="personal_information">
<action>DELETE</action>
<xsl:apply-templates select="node()"/>
</xsl:template>
</xsl:stylesheet>

blank Attribute with value in XML with XSLT transformation

I have below XMl and I need to replace root="" with Dynamic GUID value. this can be anywhere in XML document. it does not work with below XSLT. This is just the extended text to post successfully.
<ClinicalDocument xmlns="urn:hl7-org:v3">
<templateId root="2.16.840.1.113883.10.20.22.1.2" extension="2015-08-01"/>
<id root=""/>
<code code="34133-9" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LN"
displayName="Summarization of Episode Note"/>
<title>Patient Summary Document</title>
<languageCode code="en-US"/>
<component>
<structuredBody>
<component>
<section>
<templateId root="2.16.840.1.113883.10.20.22.2.6.1"/>
<entry typeCode="DRIV">
<act classCode="ACT" moodCode="EVN">
<templateId root="2.16.840.1.113883.10.20.22.4.30"/>
<templateId root="2.16.840.1.113883.10.20.22.4.30" extension="2015-08-01"/>
<id nullFlavor="UNK"/>
<informant>
<assignedEntity>
<id root="2.16.840.1.113883.3.86.3.1" extension="STHS"/>
<addr nullFlavor="UNK"/>
<telecom nullFlavor="UNK"/>
<assignedPerson>
<name nullFlavor="UNK"/>
</assignedPerson>
<representedOrganization>
<id root="" extension="STHS" displayable="true"/>
<name>STHS</name>
<telecom nullFlavor="UNK"/>
<addr nullFlavor="UNK"/>
</representedOrganization>
</assignedEntity>
</informant>
</act>
</entry>
</section>
</component>
</structuredBody>
</component>
</ClinicalDocument>
I have below XSLT. but it does not work for above highlighted tag.
<xsl:variable name="GUID" select="'FF1122'"/>
<xsl:template match="id/#root[.='']">
<xsl:attribute name="root">
<xsl:value-of select="$GUID"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:isc="http://extension-functions.intersystems.com"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="urn:hl7-org:v3">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="GUID" select="'FF1122'"/>
<xsl:template match="ns1:id/#root[.='']">
<xsl:attribute name="root">
<xsl:value-of select="$GUID"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

XSLT – creating a numbered attribute based on the value of another attribute

From a document such as the following list:
<list>
<city ref="Paris">Paris</city>
<city ref="Rome">Rome</city>
<city ref="NYC">New York</city>
<city ref="Lisboa">Lisboa</city>
<city ref="Lisboa">Lisbon</city>
<city ref="Lisboa">Lisbonne</city>
<city ref="NYC">The Big Apple</city>
</list>
I would like to obtain a copy of this list, with an added numeric attribute derived from the #ref attribute (ideally in alphabetical order), for an output like:
<list>
<city ref="Paris" id="3">Paris</city>
<city ref="Rome" id="4">Rome</city>
<city ref="NYC" id="2">New York</city>
<city ref="Lisboa" id="1">Lisboa</city>
<city ref="Lisboa" id="1">Lisbon</city>
<city ref="Lisboa" id="1">Lisbonne</city>
<city ref="NYC" id="2">The Big Apple</city>
</list>
I suppose there is a way to use <xsl:key> to number a sorted list of my #ref attributes, but am not fluent enough to get there.
Many thanks in advance.
With XSLT 3.0 (as supported by Saxon 9.7) it is as easy as
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:variable name="cities" select="sort(distinct-values(/list/city/#ref))"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="city/#ref">
<xsl:copy/>
<xsl:attribute name="id" select="index-of($cities, .)"/>
</xsl:template>
</xsl:stylesheet>
With XSLT 2.0 we can use
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:variable name="cities" as="xs:string*">
<xsl:perform-sort select="distinct-values(/list/city/#ref)">
<xsl:sort select="."/>
</xsl:perform-sort>
</xsl:variable>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="city/#ref">
<xsl:copy/>
<xsl:attribute name="id" select="index-of($cities, .)"/>
</xsl:template>
</xsl:stylesheet>
Finally with XSLT 1.0 the above "translates" into
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl"
version="1.0">
<xsl:key name="city" match="city" use="#ref"/>
<xsl:variable name="cities-rtf">
<xsl:for-each select="/list/city[generate-id() = generate-id(key('city', #ref)[1])]">
<xsl:sort select="#ref"/>
<city id="{position()}" ref="{#ref}"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="cities" select="exsl:node-set($cities-rtf)/city"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="city/#ref">
<xsl:copy/>
<xsl:attribute name="id">
<xsl:value-of select="$cities[#ref = current()]/#id"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>

Moving a element sequence value to other element sequence

I have a certain requirement where, I need to move the sequence element values to another newly created element according to the the number of values in the original sequence.
Please find my Input XML and the Desired Output XML .
help is highly appreciated
Rule:
Move the value of Addr1 (catalogue/cd11/Location/Addr/Addr1) to
catalogue/cd11/Location/primary/original/Address1/place. primary/original/Address1/place need to be created.
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.altova.com">
<publisher>
<Name id="d123">
<Place>Chicago</Place>
</Name
<catalogue id="d1" >
<cd11 id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
<Location id="d1234">
<Addr id="d234">
<Addr1 id="d565">catherine Av</Addr1>
<Addr2 id="d566">block a</Addr2>
<City id="d567">chicago</City>
</Addr>
<Addr id="d334">
<Addr1 id="d665">Illinois st</Addr1>
<Addr2 id="d666">block a</Addr2>
<City id="d667">chicago</City>
</Addr>
</Location>
</cd11>
</catalogue>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
Output XML:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.example.com">
<publisher>
<Name id="d123">
<Place>Chicago</Place>
</Name>
<catalogue id="d1">
<cd11 id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
<Location id="d1234">
<Addr id="d234">
<Addr1 id="d565">catherine Av</Addr1>
<Addr2 id="d566">block a</Addr2>
<City id="d567">chicago</City>
</Addr>
<Addr id="d334">
<Addr1 id="d665">Illinois st</Addr1>
<Addr2 id="d666">block a</Addr2>
<City id="d667">chicago</City>
</Addr>
<primary>
<original>
<test>test value</test>
<Address1>
<place>catherine Av</place>
</Address1>
<Address1>
<place>Illinois st</place>
</Address1>
</original>
</primary>
</Location>
</cd11>
</catalogue>
<catalogue id="d3">
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
Thanks in advance.
You can write a template for Location elements that inserts the new elements and transforms the Addr1 elements:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xpath-default-namespace="http://www.altova.com" xmlns="http://www.altova.com">
<xsl:output indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="catalogue/cd11/Location">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
<primary>
<original>
<Address1>
<xsl:apply-templates select="Addr/Addr1" mode="convert"/>
</Address1>
</original>
</primary>
</xsl:copy>
</xsl:template>
<xsl:template match="Addr/Addr1" mode="convert">
<place>
<xsl:value-of select="."/>
</place>
</xsl:template>
</xsl:transform>
Online sample at http://xsltransform.net/ncdD7mv.
According to your comment and edit you do not want to copy the elements, instead you want to transform them to a new namespace, so you need to change all uses of xsl:copy of an element to create an element of the same local name but with the new namespace (which will simply work if you have the right xmlns="http://www.example.com" in the XSLT and use xsl:element name="{local-name()}"):
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xpath-default-namespace="http://www.altova.com" xmlns="http://www.example.com">
<xsl:output indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="catalogue/cd11/Location">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#* | node()"/>
<primary>
<original>
<Address1>
<xsl:apply-templates select="Addr/Addr1" mode="convert"/>
</Address1>
</original>
</primary>
</xsl:element>
</xsl:template>
<xsl:template match="Addr/Addr1" mode="convert">
<place>
<xsl:value-of select="."/>
</place>
</xsl:template>
</xsl:transform>