I want to remove namespace (xmlns="http://www.cric.com") in the root element and also the comments.
Input xml looks like this
<?xml version="1.0" encoding="UTF-8"?>
<AM xmlns="http://www.cric.com" name="Asmkl">
<!-- Sets a new value to the existing parameter -->
<set>
<Payload>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">
<soapenv:Header />
<soapenv:Body>
<web:GetCitiesByCountry>
<!--Optional:-->
<web:CountryName>india</web:CountryName>
</web:GetCitiesByCountry>
</soapenv:Body>
</soapenv:Envelope>
</Payload>
<Verb>POST</Verb>
</Set>
</AM>
I have tried
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="*[namespace-uri() = 'http://www.cric.com']">
<xsl:choose>
<xsl:when test="local-name(.)='root'">
<xsl:element name="root">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:when>
<!-- Copy other elemnts -->
<xsl:otherwise>
<xsl:element name="{name()}">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Copy the rest -->
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
This stylesheet removes from root but adding the namespace in soapenv:Envelope tag.
Desired output is
<?xml version="1.0" encoding="UTF-8"?>
<AM name="Asmkl">
<Set>
<Payload>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">
<soapenv:Header />
<soapenv:Body>
<web:GetCitiesByCountry>
<web:CountryName>india</web:CountryName>
</web:GetCitiesByCountry>
</soapenv:Body>
</soapenv:Envelope>
</Payload>
<Verb>POST</Verb>
</Set>
</AM>
but I am getting
<?xml version="1.0" encoding="UTF-8"?><AM name="Asmkl">
<!-- Sets a new value to the existing parameter -->
<Set>
<Payload>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET" xmlns="http://www.cric.com">
<soapenv:Header/>
<soapenv:Body>
<web:GetCitiesByCountry>
<!--Optional:-->
<web:CountryName>india</web:CountryName>
</web:GetCitiesByCountry>
</soapenv:Body>
</soapenv:Envelope>
</Payload>
<Verb>POST</Verb>
</Set>
</AM>
Kindly suggest. XSLT processor is 1.0
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:strip-space elements="*"/>
<!-- move elements in the default namespace into no namespace -->
<xsl:template match="*[namespace-uri() = 'http://www.cric.com']">
<xsl:element name="{local-name()}">
<xsl:copy-of select="#*"/>
<xsl:apply-templates select="*"/>
</xsl:element>
</xsl:template>
<!-- "copy" all other elements, without copying the default namespace -->
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="#*"/>
<xsl:apply-templates select="*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Applied to your example (after correcting <set> to <Set>!), the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<AM name="Asmkl">
<Set>
<Payload>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<web:GetCitiesByCountry xmlns:web="http://www.webserviceX.NET">
<web:CountryName/>
</web:GetCitiesByCountry>
</soapenv:Body>
</soapenv:Envelope>
</Payload>
<Verb/>
</Set>
</AM>
Note:
I want to remove namespace (xmlns="http://www.cric.com") in the root
element
I am not sure if you realize that the default namespace declared in the root element:
<AM xmlns="http://www.cric.com" name="Asmkl">
is also inherited by the Set and Payload elements.
Related
I want to fetch values from elements without storing values in a variable. My request is long so I'm making it short here. It contains multiple tags. I tried with my XSLT but couldn't achieve the expected output. Due to multiple tags I'm unable to get into the correct path. How can I achieve below output without using variables in my XSLT ?
Below is my xml request:
<documents>
<document>
<doc1>1234</doc1>
<doc2>4578</doc2>
<locations>
<location>
<companies>
<company>
<type>E-123</type>
<empid>E-457</empid>
<pays>
<pay>
<pay1>2L</pay1>
<pay2>4L</pay2>
</pay>
</pays>
<Pays>
<pay>
<due>2L</due>
<month>30k</month>
</pay>
</pays>
</company>
</companies>
</location>
</locations>
</document>
</documents>
Here is my expected output:
<empdetails>
<details>
<emptype>E-123</emptype>
<ID>E-457</ID>
<Payment>2L</Payment>
<Payment2>4L</Payment2>
<dueperyr>50k</dueperyr>
<duemonth>30k</duemonth>
</details>
</empdetails>
XSLT which I tried:
<xsl:stylesheet extension-element-prefixes="dp apim" version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="documents">
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<xsl:apply-templates select="/documents/document" />
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="companies">
<empdetails>
<details>
<emptype>
<xsl:value-of select="company/type"/>
</emptype>
<ID>
<xsl:value-of select="company/empid"/>
</ID>
</xsl:template>
<xsl:template match="pays">
<xsl:for-each select="pays/pay">
<Payment>
<xsl:value-of select="pay/pay1"/>
</Payment>
<Payment2>
<xsl:value-of select="pay/pay2"/>
</Payment2>
</xsl:template>
<dueperyr>
<xsl:value-of select="pay/due"/>
</dueperyr>
<duemonth>
<xsl:value-of select="pay/month"/>
</duemonth>
</xsl:for-each>
</details>
</empdetails>
</xsl:stylesheet>
You can try this
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="documents">
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<xsl:apply-templates select="/documents/document" />
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="companies">
<empdetails>
<details>
<emptype>
<xsl:value-of select="company/type"/>
</emptype>
<ID>
<xsl:value-of select="company/empid"/>
</ID>
<xsl:for-each select="company/pays">
<xsl:apply-templates select="pay"/>
</xsl:for-each>
</details>
</empdetails>
</xsl:template>
<xsl:template match="pay1">
<Payment>
<xsl:apply-templates/>
</Payment>
</xsl:template>
<xsl:template match="pay2">
<Payment2>
<xsl:apply-templates/>
</Payment2>
</xsl:template>
<xsl:template match="due">
<dueperyr>
<xsl:apply-templates/>
</dueperyr>
</xsl:template>
<xsl:template match="month">
<duemonth>
<xsl:apply-templates/>
</duemonth>
</xsl:template>
</xsl:stylesheet>
link: https://xsltfiddle.liberty-development.net/eieFA1G
I have to transform an xml file using XSLT.
I had to get in the output the some structure of the input file file, expected some changes in some elements exsiting on a CDATA element.
<soapenv:Envelope xmlns:aa="http://example.com"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<aa:importOrder>
<aa:orderNumber>00501010000342</aa:orderNumber>
<aa:data>
<![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<OrderImport xmlns="http://test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
<OrderNumber>00501010000342</OrderNumber>
<Application>
<Student>
<DataElement>
<Name>age</Name>
<Type>Int</Type>
<Value>13</Value>
</DataElement>
<DataElement>
<Name>firstName</Name>
<Type>String</Type>
<Value>taha</Value>
</DataElement>
</Student>
</Application>
</OrderImport>
]]>
</aa:data>
</aa:importOrder>
</soapenv:Body>
</soapenv:Envelope>
My expected output should be like this:
<soapenv:Envelope xmlns:aa="http://example.com"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<aa:importOrder>
<aa:orderNumber>00501010000342</aa:orderNumber>
<aa:data>
<![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<OrderImport xmlns="http://test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
<OrderNumber>00501010000342</OrderNumber>
<Application>
<Student>
<DataElement>
<Name>age</Name>
<Type>Int</Type>
**<Value>Other Value</Value>**
</DataElement>
<DataElement>
<Name>firstName</Name>
<Type>String</Type>
**<Value>Other Value</Value>**
</DataElement>
</Student>
</Application>
</OrderImport>
]]>
</aa:data>
</aa:importOrder>
</soapenv:Body>
</soapenv:Envelope>
For that i used this xsl file:
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="DataElement">
<p>
<xsl:apply-template select="name"/>
</p>
</xsl:template>
<xsl:template match="Name | Type">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="Value">
Other Value
</xsl:template>
but I didn't had the expected output.
Thanks in Advance
To parse the inner XML in the CDATA you can use parse-xml, then push the nodes through templates that change the element value, then reserialize and make sure to define the aa:data as a CDATA section 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"
xmlns:aa="http://example.com"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" cdata-section-elements="aa:data"/>
<xsl:template match="aa:data">
<xsl:copy>
<xsl:variable name="transformed">
<xsl:apply-templates select="parse-xml(replace(., '^\s+', ''))/node()"/>
</xsl:variable>
<xsl:value-of select="serialize($transformed, map { 'method' : 'xml', 'omit-xml-declaration' : false() })"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Value" xpath-default-namespace="http://test.com">
<xsl:copy>Other Value</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Could you please tell me how could I remove only the name space xmlns="http://ws.apache.org/ns/synapse" from the XML tags?
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:sap-com:document:sap:rfc:functions">
<soapenv:Body>
<urn:BAPI_QM_DEFECT_RECORDING>
<AMOUNT xmlns="http://ws.apache.org/ns/synapse">1</AMOUNT>
<DEFECT_CODE xmlns="http://ws.apache.org/ns/synapse">393</DEFECT_CODE>
<DEFECT_DESC xmlns="http://ws.apache.org/ns/synapse">393</DEFECT_DESC>
<DEFECT_PID xmlns="http://ws.apache.org/ns/synapse">601000</DEFECT_PID>
<INSPID xmlns="http://ws.apache.org/ns/synapse"/>
<ORDER xmlns="http://ws.apache.org/ns/synapse">20262950</ORDER>
<ORIGIN_PID xmlns="http://ws.apache.org/ns/synapse">600000</ORIGIN_PID>
<OVER_CONSUMP xmlns="http://ws.apache.org/ns/synapse">text</OVER_CONSUMP>
</urn:BAPI_QM_DEFECT_RECORDING></soapenv:Body></soapenv:Envelope>
you can use below code by creating element use local-name which will take name without namespaces:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:sap-com:document:sap:rfc:functions">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="urn:BAPI_QM_DEFECT_RECORDING/*">
<xsl:element name="{local-name(.)}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
I have some xml as follows...
<ns1:service1 xmlns:ns1="http://foo.com/service_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:SystemInfo>
<ns1:functionMode>Y</ns1:functionMode>
</ns1:SystemInfo>
</ns1:service>
Now I need to take it and do 2 things
Wrap in a SOAP envelope
insert a trans tag in SystemInfo
the following works for wrapping...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name = "transId" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<xsl:copy-of select="/*"/>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
</xsl:stylesheet>
Now I need to add the tag, problem is we do not know what the Namespace is (and it could change per request). So I can't hardcode it. However, it will already be in the root tag.
So after I would want...
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ns1:service1 xmlns:ns1="http://foo.com/service_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:SystemInfo>
<ns1:trans />
<ns1:functionMode>Y</ns1:functionMode>
</ns1:SystemInfo>
</ns1:service>
</soapenv:Body>
</soapenv:Envelope>
But this doesn't seem to accomplish it....
<xsl:template match="*[local-name()='SystemInfo']">
<xsl:copy>
<xsl:element name="type"/>
<xsl:call-template name="copy-children"/>
</xsl:copy>
</xsl:template>
<!-- Copy the children of the current node. -->
<xsl:template name="copy-children">
<xsl:copy-of select="./*"/>
</xsl:template>
What should the above be instead?
Instead if using xsl:copy-of which will just copy the current element without allowing you to make any changes, use xsl:apply-templates
<soapenv:Body>
<xsl:apply-templates select="#*|node()"/>
</soapenv:Body>
Then you can write a template to match your SystemInfo element, and add whatever new elements you need. You could even make use of the namespace-uri function to add it with the same namespace.
<xsl:template match="*[local-name()='SystemInfo']">
<xsl:copy>
<xsl:element name="trans" namespace="{namespace-uri()}" />
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
Try this XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="transId"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<xsl:apply-templates select="#*|node()"/>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="*[local-name()='SystemInfo']">
<xsl:copy>
<xsl:element name="trans" namespace="{namespace-uri()}" />
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
below is the input xml:
<ns:TXLife xmlns:ns="http://ACORD.org/Standards/Life/2">
<TXLifeResponse>
<TransRefGUID/>
<TransExeDate/>
<TransExeTime/>
<TransType tc="228"/>
</ns:TXLife>
and below is my XSLT :
xmlns:ns="http://ACORD.org/Standards/Life/2" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acor="http://www.foresters.com/esb/ws/wsdl/ACORD-v1.0" xmlns:ns="http://ACORD.org/Standards/Life/2">
<soapenv:Header/>
<soapenv:Body>
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="node() [local-name(.) = 'TXLife']">
<xsl:element name="ns:{local-name()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
By using this tranformation i am not able to add namespace prefix to all the child element of TXLife.
how to add namespace prefix (ns) to all child elements? so that it should look as below
<ns:TXLifeResponse>
<ns:TransRefGUID/>
<ns:TransExeDate/>
<ns:TransExeTime/>
<ns:TransType tc="228"/>
</ns:TXLife>
If you want only TXLife and descendant to be under http://ACORD.org/Standards/Life/2 namespace, use this stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://ACORD.org/Standards/Life/2"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:template match="/">
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<xsl:apply-templates/>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="*[ancestor-or-self::ns:TXLife]">
<xsl:element name="ns:{local-name()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output:
<soapenv:Envelope
xmlns:ns="http://ACORD.org/Standards/Life/2"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header />
<soapenv:Body>
<ns:TXLife>
<ns:TXLifeResponse>
<ns:TransRefGUID></ns:TransRefGUID>
<ns:TransExeDate></ns:TransExeDate>
<ns:TransExeTime></ns:TransExeTime>
<ns:TransType tc="228"></ns:TransType>
</ns:TXLifeResponse>
</ns:TXLife>
</soapenv:Body>
</soapenv:Envelope>
Your XML isn't valid, but I assume you just've missed the closing TXLifeResponse element.
The following transformation will do what you want:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<ns:TXLife xmlns:ns="http://ACORD.org/Standards/Life/2">
<TXLifeResponse>
<TransRefGUID/>
<TransExeDate/>
<TransExeTime/>
<TransType tc="228"/>
</TXLifeResponse>
</ns:TXLife>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:ns="http://ACORD.org/Standards/Life/2">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:acor="http://www.foresters.com/esb/ws/wsdl/ACORD-v1.0"
xmlns:ns="http://ACORD.org/Standards/Life/2">
<soapenv:Header/>
<soapenv:Body>
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="*">
<xsl:element name="ns:{local-name()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
Output:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:acor="http://www.foresters.com/esb/ws/wsdl/ACORD-v1.0"
xmlns:ns="http://ACORD.org/Standards/Life/2">
<soapenv:Header/>
<soapenv:Body>
<ns:TXLife>
<ns:TXLifeResponse>
<ns:TransRefGUID/>
<ns:TransExeDate/>
<ns:TransExeTime/>
<ns:TransType tc="228"/>
</ns:TXLifeResponse>
</ns:TXLife>
</soapenv:Body>
</soapenv:Envelope>
The template xsl:template match="node()[local-name(.) = 'TXLife']" is somewhat strange to me. What are you trying to accomplish? Maybe we can help explain why this isn't the appropriate way to do it.