Using multiple namespaces inside xml - xslt

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>

Related

How to remove a specific prefix using XSLT

I need to remove the ns0: prefix from the RecuperarCopiaResult node.
From <ns0:RecuperarCopiaResult> to <RecuperarCopiaResult>
Follows Input XML
<?xml version="1.0" encoding="UTF-8"?>
<ns0:RecuperarCopiaResponse xmlns:ns0="http://tempuri.org/">
<ns0:RecuperarCopiaResult><![CDATA[<Abastecimento_NF
ULTIMO_PONTEIRO="447050"><Abastecimento_NFRow><DT_PROCESS>6/2/2018
1:46:08</DT_PROCESS><CD_ABASTECIMENTO>123936138</CD_ABASTECIMENTO>
<CD_VEICULO>479077</CD_VEICULO><CD_TIPO_REGISTRO>1</CD_TIPO_REGISTRO>
<NR_BANCO>237</NR_BANCO><CD_REDE>801</CD_REDE><DC_REDE>801</DC_REDE>
<COD_POSTO>244</COD_POSTO><COD_FROTA>4941</COD_FROTA>
<COD_SUBFROTA>11264</COD_SUBFROTA><DC_SUBFROTA>R2C</DC_SUBFROTA>
<CD_COMBUSTIVEL>S</CD_COMBUSTIVEL><DC_COMBUSTIVEL>S</DC_COMBUSTIVEL>
<NR_UVE></NR_UVE><DC_PLACA>KWG8687</DC_PLACA><NM_MOTORISTA>
</NM_MOTORISTA><NR_KM_ATUAL>226076</NR_KM_ATUAL>
<NR_QTD_LITROS>139,55</NR_QTD_LITROS>
<NR_QTD_LITROS_TOTAL>139,55</NR_QTD_LITROS_TOTAL>
<CD_STATUS_ABASTECIMENTO>S</CD_STATUS_ABASTECIMENTO>
</Abastecimento_NFRow></Abastecimento_NF>]]></ns0:RecuperarCopiaResult>
</ns0:RecuperarCopiaResponse>
I am using the following xslt code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://tempuri.org/">
<xsl:output encoding='UTF-8' method="xml" indent="yes" omit-xml-
declaration="yes" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SOAP-ENV:*">
<xsl:apply-templates select="#* | node()"/>
</xsl:template>
<xsl:template match="ns0:*">
<xsl:element name="ns0:{local-name()}"
namespace="http://www.supergasbras.com.br/service/CtfAbastecimento">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
</xsl:stylesheet>
Following is the expected XML:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:RecuperarCopiaResponse
xmlns:ns0="http://www.supergasbras.com.br/service/CtfAbastecimento">
<RecuperarCopiaResult>
<Abastecimento_NF ULTIMO_PONTEIRO="447050">
<Abastecimento_NFRow>
<DT_PROCESS>6/2/2018 1:46:08</DT_PROCESS>
<CD_ABASTECIMENTO>123936138</CD_ABASTECIMENTO>
<CD_VEICULO>479077</CD_VEICULO>
<CD_TIPO_REGISTRO>1</CD_TIPO_REGISTRO>
<NR_BANCO>237</NR_BANCO>
<CD_REDE>801</CD_REDE>
<DC_REDE>801</DC_REDE>
<COD_POSTO>244</COD_POSTO>
<COD_FROTA>4941</COD_FROTA>
<COD_SUBFROTA>11264</COD_SUBFROTA>
<DC_SUBFROTA>R2C</DC_SUBFROTA>
<CD_COMBUSTIVEL>S</CD_COMBUSTIVEL>
<DC_COMBUSTIVEL>S</DC_COMBUSTIVEL>
<NR_UVE/>
<DC_PLACA>KWG8687</DC_PLACA>
<NM_MOTORISTA/>
<NR_KM_ATUAL>226076</NR_KM_ATUAL>
<NR_QTD_LITROS>139,55</NR_QTD_LITROS>
<VL_PRECO_UNITARIO>3,798</VL_PRECO_UNITARIO>
<VL_PRECO_AEP>3,798</VL_PRECO_AEP>
<VL_VALOR_TOTAL>530,01</VL_VALOR_TOTAL>
<DT_EVENTO>5/2/2018 14:37:00</DT_EVENTO>
<DT_DEBITO>26/2/2018 0:00:00</DT_DEBITO>
<DT_CREDITO>27/2/2018 0:00:00</DT_CREDITO>
<NOMEARQ>T2060218.ZZ001305.00244</NOMEARQ>
<NR_KM_PERCORRIDA>365</NR_KM_PERCORRIDA>
<NR_QTD_LITROS_TOTAL>139,55</NR_QTD_LITROS_TOTAL>
<CD_STATUS_ABASTECIMENTO>S</CD_STATUS_ABASTECIMENTO>
</Abastecimento_NFRow>
</Abastecimento_NF>
</RecuperarCopiaResult>
</ns0:RecuperarCopiaResponse>
Your question says one thing, your expected result shows something quite different. Try it this way:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tmp="http://tempuri.org/"
exclude-result-prefixes="tmp">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/tmp:RecuperarCopiaResponse">
<ns0:RecuperarCopiaResponse xmlns:ns0="http://www.supergasbras.com.br/service/CtfAbastecimento">
<xsl:apply-templates/>
</ns0:RecuperarCopiaResponse>
</xsl:template>
<xsl:template match="tmp:RecuperarCopiaResult">
<RecuperarCopiaResult>
<xsl:value-of select="." disable-output-escaping="yes"/>
</RecuperarCopiaResult>
</xsl:template>
</xsl:stylesheet>

Moving and renaming contents of an XML node

i am a newbie when it comes to XSLT translations, and have been searching with this question for a while, but did not find any answher to it. I have an XML file looking like this:
<item>
<code>I001</code>
<description>DEF</description>
<properties>
<line1>
<key>key 1</key>
<value>value 1</value>
</line1>
<line2>
<key>key 2</key>
<value>value 2</value>
</line2>
</properties>
</item>
The label-software that i need to process this data with does not cope with this kind of leveled xml, so i have to transform it to something like this
<?xml version="1.0" encoding="utf-8"?>
<item>
<code>I001</code>
<description>DEF</description>
<P1_key>key 1</P1_key>
<P1_value>value 1</P1_value>
<P2_key>key 1</P2_key>
<P2_value>value</P2_value>
</item>
So far i have come up with an xsl-file that looks like 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"/>
<!-- Identity rule -->
<xsl:template match="node() | #*">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<!-- special rules ... -->
<xsl:template match="properties/line1/*">
<xsl:element name="P1_{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="properties/line2/*">
<xsl:element name="P2_{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
This does only partly what i need (renaming the elements), wit a result looking like this:
<?xml version="1.0" encoding="utf-8"?>
<item>
<code>I001</code>
<description>DEF</description>
<properties>
<line1>
<P1_key>key 1</P1_key>
<P1_value>value 1</P1_value>
</line1>
<line2>
<P2_key>key 1</P2_key>
<P2_value>value</P2_value>
</line2>
</properties>
</item>
What i now would like to now is how to move the renamed elements (P1_key, P1_value, P2_key, P2_value) to the level.
Any hints would be appreciated.
Thanks
How about:
XSLT 1.0
<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"/>
<xsl:template match="/item">
<xsl:copy>
<xsl:copy-of select="code | description"/>
<xsl:for-each select="properties/*/key">
<xsl:element name="P{position()}_key">
<xsl:value-of select="."/>
</xsl:element>
<xsl:element name="P{position()}_value">
<xsl:value-of select="following-sibling::value[1]"/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Or perhaps:
<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"/>
<xsl:template match="/item">
<xsl:copy>
<xsl:copy-of select="code | description"/>
<xsl:for-each select="properties/*/key">
<xsl:variable name="line-num" select="substring-after(name(..), 'line')" />
<xsl:element name="P{$line-num}_key">
<xsl:value-of select="."/>
</xsl:element>
<xsl:element name="P{$line-num}_value">
<xsl:value-of select="following-sibling::value[1]"/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Of course, if there always will be exactly two lines, you could just spell it out:
<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"/>
<xsl:template match="/item">
<xsl:copy>
<xsl:copy-of select="code | description"/>
<P1_key>
<xsl:value-of select="properties/line1/key" />
</P1_key>
<P1_value>
<xsl:value-of select="properties/line1/value" />
</P1_value>
<P2_key>
<xsl:value-of select="properties/line2/key" />
</P2_key>
<P2_value>
<xsl:value-of select="properties/line2/value" />
</P2_value>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
BTW, your method could work too, if you add another template:
<xsl:template match="properties | line1 | line2">
<xsl:apply-templates />
</xsl:template>

Remove xml namespace while transformation using xslt

I am transforming XML using XSLT and facing issue while namespace removal. If I remove xmlns it works fine.
Issue 1. It doesn't delete namespace from transformed XML
Issue 2. Doesn't implements other template I have in transformation.
My Input XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Catalog xmlns="http://example.com">
<Books>
<book1>Wise1 Otherwise</book1>
<book2>Great Expectations</book2>
</Books>
<library>
<Name> Forsyth </Name>
<city> Cumming </city>
</library>
</Catalog>
Expected Result
<?xml version="1.0" encoding="UTF-8"?>
<Import>
<Books>
<book1>Wise1 Otherwise</book1>
<book2>Great Expectations</book2>
</Books>
<elab>
<Name> Forsyth </Name>
<city> Cumming </city>
</elab>
</Import>
XSL
<?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:strip-space elements="*"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#xmlns">
<xsl:element name="{local-name()}" namespace="http://example.com">
<xsl:apply-templates select="node() | #*"/>
</xsl:element>
</xsl:template>
<xsl:template match="library">
<elab>
<xsl:apply-templates />
</elab>
</xsl:template>
<xsl:template match="Catalog">
<Import>
<xsl:apply-templates />
</Import>
</xsl:template>
</xsl:stylesheet>
I think you are missing the namespace declaration in the XSLT templates to match elements:
This is my try:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://example.com">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="ns:library">
<elab>
<xsl:apply-templates />
</elab>
</xsl:template>
<xsl:template match="ns:Catalog">
<Import>
<xsl:apply-templates />
</Import>
</xsl:template>
</xsl:stylesheet>

XSLT Convert attribute to element and copy value from an other elemen

I have XML data like this
<ABC version="1.0">
<XYZ>
<ROWSET ROWS="00001">
<ROWDEF>
<COLUMN ID="ACCT_ID" LEN="016" NULL="Y"/>
<COLUMN ID="AGNT_ID" LEN="004" NULL="Y"/>
<COLUMN ID="CUST_EXTR_ID" LEN="024" NULL="Y"/>
<COLUMN ID="PI_ID" LEN="019" NULL="Y"/>
<COLUMN ID="PRIN_ID" LEN="004" NULL="Y"/>
<COLUMN ID="SYS_ID" LEN="004" NULL="Y"/>
</ROWDEF>
<ROW>
<C>6369921501000060</C>
<C>0000</C>
<C>C13093102141063422034238</C>
<C>6369921501000060 </C>
<C>1500</C>
<C>9008</C>
</ROW>
<ROW>
<C>6369921501000061</C>
<C>0001</C>
<C>C13093102141063422034231</C>
<C>6369921501000060 </C>
<C>1501</C>
<C>9001</C>
</ROW>
</ROWSET>
</XYZ>
</ABC>
And I'm trying to convert this into
<?xml version="1.0" encoding="utf-8"?>
<ABC version="1.0">
<XYZ RC="0067">
<ROWSET ROWS="00001">
<ROWDEF>
<ACCT_ID>6369921501000060</ACCT_ID>
<AGNT_ID>0000</AGNT_ID>
<CUST_EXTR_ID>C13093102141063422034238</CUST_EXTR_ID>
<PI_ID>6369921501000060</PI_ID>
<PRIN_ID>1500</PRIN_ID>
<SYS_ID>9008</SYS_ID>
</ROWDEF>
<ROWDEF>
<ACCT_ID>6369921501000061</ACCT_ID>
<AGNT_ID>0001</AGNT_ID>
<CUST_EXTR_ID>C13093102141063422034231</CUST_EXTR_ID>
<PI_ID>6369921501000060</PI_ID>
<PRIN_ID>1501</PRIN_ID>
<SYS_ID>9001</SYS_ID>
</ROWDEF>
</ROWSET>
</XYZ>
</ABC>
I have looked around and tried few things but it is not working.
Can someone help me with this.
Below is my XSLT. Thanks in advance.
<?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"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="COLUMN">
<xsl:element name="{#ID}">
<xsl:copy>
<xsl:apply-templates select="node()"></xsl:apply-templates>
</xsl:copy>
<xsl:apply-templates />
<!--<xsl:call-template name="value"></xsl:call-template>-->
</xsl:element>
</xsl:template>
<!--
<xsl:template match="ROW" name="value">
<xsl:copy>
<xsl:apply-templates select="node()"></xsl:apply-templates>
</xsl:copy>
</xsl:template>
-->
</xsl:stylesheet>
This stylesheet will mostly do what you want, but I cannot fathom how to generate the attribute for <XYZ RC="0067">.
For each ROWSET it comes across it saves the ROWDEF element in a variable, copies all attribute nodes, and then processes each ROW element. The position of each C element in the ROW is caclulated, and the COLUMN in the corresponding position within the stored ROWDEF element is used to fetch an element name from the ID attribute.
<?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"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="ROWSET">
<xsl:variable name="columns" select="ROWDEF/COLUMN"/>
<xsl:copy>
<xsl:apply-templates select="#*" />
<xsl:for-each select="ROW">
<ROWDEF>
<xsl:for-each select="C">
<xsl:variable name="pos" select="position()"/>
<xsl:element name="{$columns[$pos]/#ID}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</ROWDEF>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
output
<?xml version="1.0" encoding="utf-8"?>
<ABC version="1.0">
<XYZ>
<ROWSET ROWS="00001">
<ROWDEF>
<ACCT_ID>6369921501000060</ACCT_ID>
<AGNT_ID>0000</AGNT_ID>
<CUST_EXTR_ID>C13093102141063422034238</CUST_EXTR_ID>
<PI_ID>6369921501000060 </PI_ID>
<PRIN_ID>1500</PRIN_ID>
<SYS_ID>9008</SYS_ID>
</ROWDEF>
<ROWDEF>
<ACCT_ID>6369921501000061</ACCT_ID>
<AGNT_ID>0001</AGNT_ID>
<CUST_EXTR_ID>C13093102141063422034231</CUST_EXTR_ID>
<PI_ID>6369921501000060 </PI_ID>
<PRIN_ID>1501</PRIN_ID>
<SYS_ID>9001</SYS_ID>
</ROWDEF>
</ROWSET>
</XYZ>
</ABC>

i want to adding "xmlns" attribute in xml file using xslt

I want to following xml file output:
<?xml version="1.0" encoding="ISO-8859-1" ?>
- <T0020 xsi:schemaLocation="http://www.safersys.org/namespaces/T0020V1 T0020V1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.safersys.org/namespaces/T0020V1">
- <INTERFACE>
<NAME>SAFER</NAME>
<VERSION>04.02</VERSION>
</INTERFACE>
for that i have following xslt file:
<xsl:template match="T0020" >
<xsl:copy>
<xsl:attribute name="xsi:schemaLocation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">http://www.safersys.org/namespaces/T0020V1 T0020V1.xsd </xsl:attribute>
//some code here...............//
<xsl:copy>
so i add xmlns="http://www.safersys.org/namespaces/T0020V1" attribute under <T0020> tag??
This transformation:
<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:variable name="vDefaultNS"
select="'http://www.safersys.org/namespaces/T0020V1'"/>
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{$vDefaultNS}">
<xsl:copy-of select="namespace::* | #*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
when applied on this XML document:
<T0020 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.safersys.org/namespaces/T0020V1 T0020V1.xsd"
>
<INTERFACE>
<NAME>SAFER</NAME>
<VERSION>04.02</VERSION>
</INTERFACE>
</T0020>
produces the wanted result:
<T0020 xmlns="http://www.safersys.org/namespaces/T0020V1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.safersys.org/namespaces/T0020V1 T0020V1.xsd">
<INTERFACE>
<NAME>SAFER</NAME>
<VERSION>04.02</VERSION>
</INTERFACE>
</T0020>
Do note that xmlns is not an attribute, but denotes a namespace declaration.
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}" namespace="http://www.safersys.org/namespaces/T0020V1">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="T0020">
<xsl:element name="{name()}" namespace="http://www.safersys.org/namespaces/T0020V1">
<xsl:attribute name="xsi:schemaLocation">http://www.safersys.org/namespaces/T0020V1 T0020V1.xsd</xsl:attribute>
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
With this input:
<T0020>
<INTERFACE>
<NAME>SAFER</NAME>
<VERSION>04.02</VERSION>
</INTERFACE>
</T0020>
Output:
<T0020 xsi:schemaLocation="http://www.safersys.org/namespaces/T0020V1 T0020V1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.safersys.org/namespaces/T0020V1">
<INTERFACE>
<NAME>SAFER</NAME>
<VERSION>04.02</VERSION>
</INTERFACE>
</T0020>
Note: Namespace node are not attributes nodes. If you want that elements in no namespace gets output under some namespace you need the xsl:element/#namespace.