xslt and SOAP namespace: how to add - xslt

I have this basic SOAP response:
<?xml version="1.0" encoding="WINDOWS-1252" standalone="yes"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body xmlns="http://www.xxx.com/dotnet/types/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<a>
<b>
<c>
c-value
</c>
b-value
</b>
a-value
</a>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
and I want to output just the value of the c node: c-value.
I don't understand why this xsl is NOT working:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
>
<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:value-of select="//c"/>
</xsl:template>
</xsl:stylesheet>
It seems that the problem is in the name space at <SOAP-ENV:Body xmlns="http://www.xxx.com/dotnet/types/"
If I remove it, it works.
I guess I should change the xpath in select="//c" or add somewhere in the xls the needed namespace, but I can't get it right!

ok, this link was helpful: How to 'select' from XML with namespaces?
I added the namespace like this:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xxx="http://www.xxx.com/dotnet/types/"
>
<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:value-of select="//xxx:c"/>
</xsl:template>
</xsl:stylesheet>
First the xmlns:xxx is added to the xlst and then the XPath becomes //xxx:c.
Writing questions in SO, solves problems...

Related

Match node with namespaces [duplicate]

This question already has answers here:
XSLT with XML source that has a default namespace set to xmlns
(3 answers)
Closed 1 year ago.
I have this original xml:
<Document xmlns="http://schema.infor.com/InforOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schema.infor.com/InforOAGIS/2 http://schema.infor.com/2.12.x/InforOAGIS/BODs/SyncCaptureDocument.xsd" releaseID="9.2" versionID="2.12.2">
<Application>
<Sender>
<LogicalID>lid://infor.daf.1</LogicalID>
<Code>OnError</Code>
</Sender>
<CreationDateTime>2021-06-10T23:07:36.193Z</CreationDateTime>
</Application>
</Document>
My XSLT so far:
<?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:ns0="http://schema.infor.com/InforOAGIS/2 http://schema.infor.com/2.12.x/InforOAGIS/BODs/SyncCaptureDocument.xsd"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes" html-version="5"/>
<xsl:template match="/">
<Transaction xmlns="http://schema.infor.com/InforOAGIS/2"
languageCode="en-US"
releaseID="9.2"
systemEnvironmentCode="Production"
versionID="2.8.0">
<ApplicationArea>
<Sender>
<LogicalID>
<xsl:value-of select="ns0:Document/ns0:Application/ns0:Sender/ns0:LogicalID"/>
</LogicalID>
<Code>Add</Code>
</Sender>
<CreationDateTime>2021-06-10T23:07:36.193Z</CreationDateTime>
</ApplicationArea>
</Transaction>
</xsl:template>
</xsl:stylesheet>
I cannot match the <LogicalID> node with the code above. I think it's because of the namespaces.
Any help is appreciated. Link to the xslt: https://xsltfiddle.liberty-development.net/eieFA13/1
The namespace declaration in the XSLT is wrong, see the fix in https://xsltfiddle.liberty-development.net/eieFA13/2 to bind only the namespace name (e.g. xmlns:ns0="http://schema.infor.com/InforOAGIS/2") or https://xsltfiddle.liberty-development.net/eieFA13/3 to ease the task by using xpath-default-namespace (e.g. xpath-default-namespace="http://schema.infor.com/InforOAGIS/2").
On the other hand it sounds more as if you want to change the Sender/Code element:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xpath-default-namespace="http://schema.infor.com/InforOAGIS/2"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Sender/Code">
<xsl:copy>Add</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/eieFA13/4

How can I add a CSS declaration to an XML document using XSLT?

I have many XML files that I want to process with XSLT. I want the result to include custom CSS for the purpose of displaying the files a distinct way in Oxygen’s Author mode.
Input:
<?xml version="1.0" encoding="utf-8"?>
<alto xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/standards/alto/ns-v2# http://www.loc.gov/standards/alto/alto-v2.0.xsd" xmlns="http://www.loc.gov/standards/alto/ns-v2#">
<!—more XML-->
</alto>
XSL:
<?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"
xpath-default-namespace="http://www.loc.gov/standards/alto/ns-v2#"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!—A series of templates that transform the XML-->
</xsl:stylesheet>
Desired Output:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="my-style.css"?>
<alto xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.loc.gov/standards/alto/ns-v2#"
xsi:schemaLocation="http://www.loc.gov/standards/alto/ns-v2# http://www.loc.gov/standards/alto/alto-v2.0.xsd">
<!—more XML-->
</alto>
What do I need to add to my stylesheet to get the declaration to display in each XML file?
Use the xsl:processing-instruction instruction.
So your stylesheet could look like this:
<?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"
xpath-default-namespace="http://www.loc.gov/standards/alto/ns-v2#"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:processing-instruction name="xml-stylesheet">href="my-style.css"</xsl:processing-instruction>
<xsl:apply-templates select="node()|#*" />
</xsl:template>
<!-- Identity template -->
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output is:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="my-style.css"?>
<alto xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.loc.gov/standards/alto/ns-v2#"
xsi:schemaLocation="http://www.loc.gov/standards/alto/ns-v2# http://www.loc.gov/standards/alto/alto-v2.0.xsd"/>
Add
<xsl:template match="/">
<xsl:processing-instruction name="xml-stylesheet">href="my-style.css"</xsl:processing-instruction>
<xsl:next-match/>
</xsl:template>
at the end of the stylesheet or make sure you edit the template you have for match="/" and insert the <xsl:processing-instruction name="xml-stylesheet">href="my-style.css"</xsl:processing-instruction> there.

XSLT keep namespace on output

I need help preserving the namespace on XSLT transformation. I see other threads have solutions, but I don't understand them. When I use the XSLT transformation below, all the namespace disappears. Below is what I'm trying to accomplish. Any help is much appreciated! Thank you!
Before transform XML:
<?xml version='1.0' encoding='UTF-8'?>
<Worker
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:this="this.file/eib"
xmlns:is="java:com.workday.esb.intsys.xpath.ParsedIntegrationSystemFunctions"
xmlns:tv="java:com.workday.esb.intsys.TypedValue">
<Detail>
<EmployeeID>123456</EmployeeID>
<PayCode>Earning</PayCode>
<Amount>4243.20</Amount>
</Detail>
<Detail>
<EmployeeID>123456</EmployeeID>
<PayCode>Deduction</PayCode>
<Amount>2265.60</Amount>
</Detail>
</Worker>
My XSLT transformation:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" exclude-result-prefixes="xsl wd is xsd this env"
xmlns:wd="urn:com.workday/bsvc"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:is="java:com.workday.esb.intsys.xpath.ParsedIntegrationSystemFunctions"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:this="urn:this-stylesheet">
<xsl:output indent="yes" method="xml"/>
<xsl:template match="/">
<xsl:copy>
<Worker>
<xsl:for-each select="Worker" >
<Detail>
<EmployeeID><xsl:value-of select="Detail[(PayCode ='Earning')]/EmployeeID"/></EmployeeID>
<PayCode><xsl:value-of select="Detail[(PayCode ='Earning')]/PayCode"/></PayCode>
<Amount><xsl:value-of select="Detail[(PayCode ='Earning') and (string-length(Amount) > 0)]/Amount"/></Amount>
</Detail>
</xsl:for-each>
</Worker>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Desired output:
<?xml version="1.0" encoding="UTF-8"?>
<Worker
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:this="this.file/eib"
xmlns:is="java:com.workday.esb.intsys.xpath.ParsedIntegrationSystemFunctions"
xmlns:tv="java:com.workday.esb.intsys.TypedValue">
<Detail>
<EmployeeID>123456</EmployeeID>
<PayCode>Earning</PayCode>
<Amount>4243.20</Amount>
</Detail>
</Worker>
At least in XSLT 2.0 (the version you used), namespaces disappear because you used exclude-result-prefixes attribute.
Just remove it and all namespaces included in your XSLT sheet, except for xsl, will be presented in the output, in the order of appearance.
But if you decided to omit all namespaces, it is easier to write exclude-result-prefixes="#all", instead of writing them again.
I can see no good reason to keep namespace declarations that are not used in your output. But if you really want to have them, why don't you simply copy them (as part of their parent element) - for example:
XSLT
<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:strip-space elements="*"/>
<xsl:template match="/Worker">
<xsl:copy>
<xsl:copy-of select="Detail[PayCode ='Earning']"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When this is applied to your input example, the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<Worker xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:this="this.file/eib"
xmlns:is="java:com.workday.esb.intsys.xpath.ParsedIntegrationSystemFunctions"
xmlns:tv="java:com.workday.esb.intsys.TypedValue">
<Detail>
<EmployeeID>123456</EmployeeID>
<PayCode>Earning</PayCode>
<Amount>4243.20</Amount>
</Detail>
</Worker>
Demo: http://xsltransform.net/gVhD8Qt

Need duplicate xmlns:xsi declaration in child element

Can't get this working.
Running a xml to xml xslt-transformation.
Want this to be included in AppHdr as well (requirement of receiver of xml output):
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Sample of xslt:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:template match="/">
<Env:RequestPayload xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Env="urn:xxxxx:xxxxx:xsd:benvelope" xsi:schemaLocation="xyz IBenvelope.xsd">
<AppHdr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:xxx:std:xxx:xxxxx:eee:xsd:hhh.01" xsi:schemaLocation="abc.xsd">
</AppHdr>
<Document xmlns="xxxxxxxxxxxxxx" xmlns:xs="http://www.w3.org/2001/XMLSchema">
</Document>
</Env:RequestPayload>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="utf-8"?>
<Env:RequestPayload xsi:schemaLocation="xyz IBenvelope.xsd" xmlns:Env="urn:xxxxx:xxxxx:xsd:benvelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AppHdr xsi:schemaLocation="abc.xsd" xmlns="urn:xxx:std:xxx:xxxxx:eee:xsd:hhh.01" />
<Document xmlns="xxxxxxxxxxxxxx" xmlns:xs="http://www.w3.org/2001/XMLSchema" />
</Env:RequestPayload>

Synapse XPath Extension in XSLT

Is it possible to access Synapse XPATH extension from an XSLT. I want to use the get-property function in an XSLT, is it possible?
Ex:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:synapse="http://ws.apache.org/ns/synapse"
exclude-result-prefixes="synapse"
version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" />
<xsl:template match="/">
<xsl:copy-of select="synapse:get-property('paramName')" />
</xsl:template>
</xsl:stylesheet>