Dear Experts, I have Input request with SOAP Env, from that which need to be capture only body of by using XSLT
And at the same time, need to remove namespace on the element and also name space prefix of every element.
Input Request
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:v1="http://xmldefs. ag.com/Applications/eer/V1">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<v1:ProcessDistr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<v1:Group xmlns:ns2="http://xmldefs.ag.com/DD/Commons">
<v1:GroupID>437848</v1: GroupID>
<v1:Status>true</v1:Status>
<v1:Parent>45434554</v1:Parent>
</v1:Group>
</v1:ProcessDistr>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Output Received
<?xml version="1.0" encoding="UTF-8"?>
<v1:ProcessDistr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsu=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xmldefs. ag.com/Applications/eer/V1">
<v1:Group xmlns:ns2="http://xmldefs.ag.com/DD/Commons">
<v1:GroupID>437848</v1: GroupID>
<v1:Status>true</v1:Status>
<v1:Parent>45434554</v1:Parent>
</v1:Group>
</v1:ProcessDistr>
XSLT code
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:v1="http://xmldefs. ag.com/Applications/eer/V1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsltc="http://xml.apache.org/xalan/xsltc" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sap="http://www.sap.com/sapxsl" xmlns:prof="http://ixult.net/ProfileExchange" exclude-result-prefixes ="v1" xmlns:wsu=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<!-- Output -->
<xsl:output encoding="UTF-8" indent="yes" method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<!-- filter ProcessDistr-->
<xsl:copy-of select="//v1:ProcessDistr"/>
</xsl:template>
</xsl:stylesheet>
I am expecting this output
<?xml version="1.0" encoding="UTF-8"?>
<ProcessDistr >
<Group >
<GroupID>437848</GroupID>
<Status>true</Status>
<Parent>45434554</Parent>
</Group>
</ProcessDistr>
Could you please share me your view on this.
Thank you very much.
With Best Regards,
Sateesh N
The result you want can be achieved simply by:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:v1="http://xmldefs.ag.com/Applications/eer/V1">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="v1:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Demo (after removing the superfluous spaces from your input): https://xsltfiddle.liberty-development.net/pPzifqc
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:v1="http://xmldefs. ag.com/Applications/eer/V1"
xmlns:ns2="http://xmldefs.ag.com/DD/Commons"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xs SOAP-ENV wsu v1 ns2 xsi"
version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="SOAP-ENV:Envelope">
<xsl:apply-templates select="SOAP-ENV:Body/v1:ProcessDistr"/>
</xsl:template>
<xsl:template match="v1:ProcessDistr">
<xsl:element name="ProcessDistr">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="v1:Group">
<xsl:element name="Group">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="v1:GroupID">
<xsl:element name="GroupID">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="v1:Status">
<xsl:element name="Status">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="v1:Parent">
<xsl:element name="Parent">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Try this
Related
Here's my input XML:
<?xml version="1.0" encoding="UTF-8"?>
<Sync
xmlns="http://schema.infor.com/InforOAGIS/2" languageCode="en-US" versionID="2.8.0">
<Data>
<ID>0001</ID>
<Text>ABCD</Text>
</Data>
</Sync>
And here's my expected outcome:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:Sync xmlns:ns0="http://schema.infor.com/InforOAGIS/2"
languageCode="en-US"
versionID="2.8.0">
<DataArea xmlns:dns="http://schema.infor.com/InforOAGIS/2" xmlns="">
<ID>0001</ID>
<Text>ABCD</Text>
</DataArea>
</ns0:Sync>
My current XSLT as below (https://xsltfiddle.liberty-development.net/nbiE19N).
There are 2 problems:
I have the extra xmlns="" in DataArea element. I only want to add the dns namespace.
I cannot add the ns0 prefix for my namespace
<xsl:stylesheet version="2.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="/*:Sync">
<xsl:copy>
<xsl:copy-of select="#*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*:Sync/*:Data">
<DataArea>
<xsl:namespace name="dns" select="'http://schema.infor.com/InforOAGIS/2'"/>
<ID>
<xsl:value-of select="/*:Sync/*:Data/*:ID"/>
</ID>
<Text>
<xsl:value-of select="/*:Sync/*:Data/*:Text"/>
</Text>
</DataArea>
</xsl:template>
</xsl:stylesheet>
Any suggestion is appreciated!
Does this return the expected result:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://schema.infor.com/InforOAGIS/2">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Sync">
<ns0:Sync xmlns:ns0="http://schema.infor.com/InforOAGIS/2">
<xsl:copy-of select="#*"/>
<xsl:apply-templates/>
</ns0:Sync>
</xsl:template>
<xsl:template match="Data">
<DataArea xmlns:dns="http://schema.infor.com/InforOAGIS/2">
<xsl:apply-templates/>
</DataArea>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
P.S. I am not sure why you need the xmlns:dns="http://schema.infor.com/InforOAGIS/2" declaration; it's not being used anywhere.
I want to replace the namespace of the following XML Document
<?xml version="1.0" encoding="UTF-8"?>
<ns0:Document xmlns:ns0="http://mydata.com/H2H/Automation">
<CstmrCdtTrfInitn>
<GrpHdr>
</GrpHdr>
</CstmrCdtTrfInitn>
</ns0:Document>
with the following
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CstmrCdtTrfInitn>
<GrpHdr>
</GrpHdr>
</CstmrCdtTrfInitn>
</Document>
Any idea about XSLT which can convert this?
I have tried the following XSL, but it is adding the namespace with second Node and also not able to remove first namespace.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes"/>
<xsl:template match="/*">
<xsl:element name="{local-name()}" namespace="http://www.w3.org/2001/XMLSchema-instance">
<xsl:copy-of select="./*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Your requirement can be a bit tricky: replacing the default namespace of the Document element is straightforward. But adding the unused xslns:xsi namespace in XSLT-1.0 requires the EXSLT extension and a special technique explained by Michael Kay in reply to this question. It involves creating an unused element in a global variable whose namespace is then copied in the template replacing the default namespace. In XSLT-2.0 and above this would be easier (see below).
The EXSLT extension is not available in all XSLT-1.0 processors. But it is necessary to create a node-set from the variable.
So all namespaces are to be defined in the xsl:stylesheet element, and then the root element (here ns0:Document) is matched by a template and replaced with its local-name() part with the new default namespace added, followed by copying the "dummy" namespace of the element defined in the variable.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://mydata.com/H2H/Automation" xmlns:urn="urn:iso:std:iso" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ext="http://exslt.org/common">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<!-- identity template (except elements)-->
<xsl:template match="node()[not(self::*)]|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*" />
</xsl:copy>
</xsl:template>
<xsl:variable name="nsXSI">
<xsl:element name="xsi:dummy" namespace="http://www.w3.org/2001/XMLSchema-instance" />
</xsl:variable>
<xsl:template match="ns0:*|*">
<xsl:element name="{local-name()}" namespace="urn:iso:std:iso">
<xsl:copy-of select="ext:node-set($nsXSI)/*/namespace::xsi" />
<xsl:apply-templates select="node() | #*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Output should be as expected, even in XSLT-1.0:
<Document xmlns="urn:iso:std:iso" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CstmrCdtTrfInitn>
<GrpHdr>
</GrpHdr>
</CstmrCdtTrfInitn>
</Document>
The simplified solution requires an XSLT-2.0 capable processor. Then you can use the xsl:namespace instruction as follows and don't need the "dummy" variable:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://mydata.com/H2H/Automation">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<!-- identity template (except elements)-->
<xsl:template match="node()[not(self::element())]|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*" />
</xsl:copy>
</xsl:template>
<xsl:template match="ns0:*|*">
<xsl:element name="{local-name(.)}" namespace="urn:iso:std:iso">
<xsl:namespace name="xsi">http://www.w3.org/2001/XMLSchema-instance</xsl:namespace>
<xsl:apply-templates select="node() | #*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The output is the same.
The above XSLT-2.0 solution could be further simplified by using XSLT-3.0+'s xsl:mode to replace the identity template with
<xsl:mode on-no-match="shallow-copy"/>
Is there a reason why you cannot do simply:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://mydata.com/H2H/Automation"
exclude-result-prefixes="ns0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="urn:iso:std:iso">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="/ns0:Document">
<Document xmlns="urn:iso:std:iso" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:apply-templates/>
</Document>
</xsl:template>
</xsl:stylesheet>
I have multiple occurence nodes which need to be generated at output using XSLT transformation. Could you please help me on this.
Following XSLT code only generate one node occurrence only. Could you please help me with below XSLT code how to generate multiple nodes elements in Input XML
Input XML
<?xml version="1.0" encoding="UTF-8" ?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Body>
<ns1:getGenResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
<ns1:getGenReturn xsi:type="soapenc:Array" soapenc:arrayType="xsd:anyType[2]" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
</ns1:getGenReturn>
</ns1:getGenResponse>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:Gen" xmlns:soapenc=http://schemas.xmlsoap.org/soap/encoding/>
<name xsi:type="xsd:string">ULM</name>
<mail xsi:type="xsd:string">ulm#gmail.com</mail>
</multiRef>
<multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns3:Gen" " xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<name xsi:type="xsd:string">ABC</name>
<mail xsi:type="xsd:string">abc#gmail.com</mail>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
XSLT Code used for this transformation
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" x
xmlns:response="http://tempuri.org/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Output -->
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:if test="//soap:Body/multiRef">
<xsl:element name="getGenResponse">
<xsl:element name="getGenReturn">
<xsl:element name="name"><xsl:value-of select="//name"/></xsl:element>
<xsl:element name="mail"><xsl:value-of select="//mail"/></xsl:element>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:template>
<!-- 'Copy ' node -->
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output from above XSLT
<?xml version="1.0" encoding="UTF-8"?>
<getGenResponse>
<getGenReturn>
<name> ULM </name>
<mail>ulm#gmail.com<mail>
</getGenReturn>
/getGenResponse>
Output expected
<?xml version="1.0" encoding="UTF-8"?>
<getGenResponse>
<getGenReturn>
<name> ULM </name>
<mail>ulm#gmail.com<mail>
</getGenReturn>
<getGenReturn>
<name>ABC</name>
<mail>abc#gmail.com<mail>
</getGenReturn>
/getGenResponse>
At you moment all you are doing is testing a multiRef element exists, and outputting only one new getGenReturn element.
All you really need to do is replace the xsl:if with xsl:for-each to select all the elements, then you will get one getGenReturn for each. And also change the xsl:value-of to use a relative path
<xsl:template match="/">
<xsl:element name="getGenResponse">
<xsl:for-each select="//soap:Body/multiRef">
<xsl:element name="getGenReturn">
<xsl:element name="name"><xsl:value-of select="name"/></xsl:element>
<xsl:element name="mail"><xsl:value-of select="mail"/></xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
Or better still, do this, as xsl:element is not really needed here if you are using static names
<xsl:template match="/">
<getGenResponse>
<xsl:for-each select="//soap:Body/multiRef">
<getGenReturn>
<name><xsl:value-of select="name"/></name>
<mail><xsl:value-of select="mail"/></mail>
</getGenReturn>
</xsl:for-each>
</getGenResponse>
</xsl:template>
Note, you don't actually need the identity template in this case. Try this XSLT:
<xsl:stylesheet version="1.0" xmlns:response="http://tempuri.org/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="soap response">
<!-- Output -->
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<getGenResponse>
<xsl:for-each select="//soap:Body/multiRef">
<getGenReturn>
<name><xsl:value-of select="name"/></name>
<mail><xsl:value-of select="mail"/></mail>
</getGenReturn>
</xsl:for-each>
</getGenResponse>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:response="http://tempuri.org/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="soap response">
<!-- Output -->
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<getGenResponse>
<xsl:for-each select="//soap:Body/multiRef">
<getGenReturn>
<name><xsl:value-of select="name"/></name>
<mail><xsl:value-of select="mail"/></mail>
</getGenReturn>
</xsl:for-each>
</getGenResponse>
</xsl:template>
</xsl:stylesheet>
I have a problem to retrieve my input data when I do an xsl transformation.
This is my original xml input (input xml)
<?xml version="1.0" encoding="UTF-8"?> <ns2:pointOfSale
xmlns:ns2="http://example.net/.."
mode="CREATE" timestamp="2018-10-12T09:34:53.14+02:00"><ns2:id
type="AMP">15573</ns2:id></ns2:pointOfSale>
This is my output result (output xml)
<?xml version="1.0" encoding="utf-8"?><clients xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="setClients.xsd" encryptedData="N"><client clientID=""></client></clients>
this is my xsl
<?xml version="1.1" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns2="http://example.net/.."
exclude-result-prefixes="xs xd"
version="2.0">
<xsl:output method="xml" version="1.0" encoding="utf-8" omit-xml-declaration="no" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:element name="clients">
<xsl:attribute
name="xsi:noNamespaceSchemaLocation">setClients.xsd</xsl:attribute>
<xsl:attribute name="encryptedData">N</xsl:attribute>
<xsl:element name="client">
<xsl:attribute name="clientID" >
<xsl:value-of select="ns2:id"/>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Like you see, the value of element ID is empty ("")
What's the problem? is it the match() ? Maybe a problem of namespace?
thank you.
There are two reasons why <xsl:value-of select="id"/> is not returning anything.
Firstly, your template matches "/" which is the document node. This is the parent of the ns2:pointOfSale node in your XML. The document node does not have id as a child, so <xsl:value-of select="id"/> will not find anything. To fix this, you should match the root element (ns2:pointOfSale in this case) instead
<xsl:template match="/*">
The second issue is with namespaces. Assuming there was a namespace declaration in your XML of the form xmlns:ns2="xxx.xxxx" you would add the same declaration in your XSLT (on the xsl:stylesheet element) and then you could this.
<xsl:value-of select="ns2:id"/>
Without any reference to the namespace in your XSLT, it would be looking for an id element in no namespace.
Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xs xd"
xmlns:ns2="xxx.xxxx"
version="2.0">
<xsl:output method="xml" version="1.0" encoding="utf-8" omit-xml-declaration="no" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
<xsl:element name="clients">
<xsl:attribute
name="xsi:noNamespaceSchemaLocation">setClients.xsd</xsl:attribute>
<xsl:attribute name="encryptedData">N</xsl:attribute>
<xsl:element name="client">
<xsl:attribute name="clientID" >
<xsl:value-of select="ns2:id"/>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Actually, as you are using XSLT 2.0, you could use xpath-default-namespace instead, which would mean XSLT would treat any unprefixed element in a select expression as part of that namespace.
Try this too....
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xs xd"
xpath-default-namespace="xxx.xxxx"
version="2.0">
<xsl:output method="xml" version="1.0" encoding="utf-8" omit-xml-declaration="no" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
<xsl:element name="clients">
<xsl:attribute
name="xsi:noNamespaceSchemaLocation">setClients.xsd</xsl:attribute>
<xsl:attribute name="encryptedData">N</xsl:attribute>
<xsl:element name="client">
<xsl:attribute name="clientID" >
<xsl:value-of select="id"/>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Better still, use Attribute Value Templates (and avoid the use of xsl:element) to simplify the XSLT to this...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xs xd"
xpath-default-namespace="xxx.xxxx"
version="2.0">
<xsl:output method="xml" version="1.0" encoding="utf-8" omit-xml-declaration="no" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
<clients xsi:noNamespaceSchemaLocation="setClients.xsd" encryptedData="N">
<client clientID="{id}" />
</clients>
</xsl:template>
</xsl:stylesheet>
My problem is how to add namespace and prefix for all elements and attributes using XSLT?
My input xml as is....
<ProcessCreditMemo xmlns='CreditMemo'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
<ORDER_HEADERDetails>
<ORDER_HEADER>
<NAME>0010185214</NAME>
to be...
<ns0:ProcessCreditMemo xmlns='CreditMemo'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:ns0="http://tempuri.org/">
<ns0:ORDER_HEADERDetails>
<ns0:ORDER_HEADER>
<ns0:NAME>0010185214</NAME>
I need add the prefix "ns0:" for all elements and attributes, and add the namespace "xmlns:ns0="http://tempuri.org/" in the header "ProcessCreditMemo".
I am trying to build a XSLT to do it...
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|text()|#*">
<xsl:copy>
<xsl:if test="local-name()='ProcessCreditMemo'">
<xsl:attribute name="xmlns" namespace="http://tempuri.org/" />
</xsl:if>
but the resulting XML duplicates the prefix with empty value.
<ProcessCreditMemo xmlns="CreditMemo"
xmlns:ns0="http://tempuri.org/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
ns0:xmlns="">
This transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://tempuri.org/">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="ns0:{name()}" namespace="http://tempuri.org/">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
when applied on the (corrected) provided input (severely malformed, incomplete XML):
<ProcessCreditMemo xmlns='CreditMemo'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
<ORDER_HEADERDetails>
<ORDER_HEADER>
<NAME>0010185214</NAME>
</ORDER_HEADER>
</ORDER_HEADERDetails>
</ProcessCreditMemo>
produces the wanted, correct result (not the severely malformed/incomplete provided wanted-result):
<ns0:ProcessCreditMemo xmlns:ns0="http://tempuri.org/" xmlns="CreditMemo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ns0:ORDER_HEADERDetails>
<ns0:ORDER_HEADER>
<ns0:NAME>0010185214</ns0:NAME>
</ns0:ORDER_HEADER>
</ns0:ORDER_HEADERDetails>
</ns0:ProcessCreditMemo>