Synapse XPath Extension in XSLT - 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>

Related

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.

XPath navigation with varying namespace-prefixes

I'm currently struggling with the XPath matching of XML input in my XSL-FO stylesheets. The root XML can have a varying namespace-prefix (in this example ns1, but could change anytime to something else and have no control of). The only information I have is the namespace (in my example http://www.foo.com/foo1).
XML input
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:letter xmlns:ns1="http://www.foo.com/foo1" xmlns:ns2="http://www.foo.com/foo2">
<surname>Doe</surname>
<givenname>John</givenname>
...
</ns1:letter>
XSL-FO stylesheet
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" xpath-default-namespace="http://www.foo.com/foo1">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<fo:root>
...
<!-- this does not match !!! -->
<xsl:value-of select="/letter/surname"/>
...
</fo:root>
</xsl:template>
</xsl:stylesheet>
In your XML, letter is in a namespace, but surname isn't. By using xpath-default-namespace in your XSLT you are assuming all unprefixed elements in your xpath are in that namespace.
What you could do, is explicitly declare the namespace with a prefix. The prefix does not have to match the XML, it is totally arbitrary. It is the namespace URL that has to match for it to work
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:foo="http://www.foo.com/foo1">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<fo:root>
<xsl:value-of select="/foo:letter/surname"/>
</fo:root>
</xsl:template>
</xsl:stylesheet>

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>

xslt and SOAP namespace: how to add

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...

XSLT remove unwanted elements

I have XML
<getInquiryAboutListReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<inquiryAbouts>
<inquiryAbout>
<code>Code</code>
<nameKk>Something</nameKk>
<nameRu>Something</nameRu>
<documents xsi:nil="true"/>
</inquiryAbout>
</inquiryAbouts>
</getInquiryAboutListReturn>
And I want to process it with XSLT to copy all XML
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" />
<xsl:template match="/">
<xsl:copy-of select="//getInquiryAboutListReturn/inquiryAbouts"/>
</xsl:template>
</xsl:stylesheet>
How could I copy all XML without <documents xsi:nil="true"/> or without xsi:nil="true"?
Desired output XML
<getInquiryAboutListReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<inquiryAbouts>
<inquiryAbout>
<code>Code</code>
<nameKk>Something</nameKk>
<nameRu>Something</nameRu>
</inquiryAbout>
</inquiryAbouts>
</getInquiryAboutListReturn>
This simple XSLT:
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- TEMPLATE #1 -->
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<!-- TEMPLATE #2 -->
<xsl:template match="*[#xsi:nil = 'true']" />
</xsl:stylesheet>
...when applied to the OP's source XML:
<?xml version="1.0"?>
<getInquiryAboutListReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<inquiryAbouts>
<inquiryAbout>
<code>Code</code>
<nameKk>Something</nameKk>
<nameRu>Something</nameRu>
<documents xsi:nil="true"/>
</inquiryAbout>
</inquiryAbouts>
</getInquiryAboutListReturn>
...produces the expected result XML:
<?xml version="1.0"?>
<getInquiryAboutListReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<inquiryAbouts>
<inquiryAbout>
<code>Code</code>
<nameKk>Something</nameKk>
<nameRu>Something</nameRu>
</inquiryAbout>
</inquiryAbouts>
</getInquiryAboutListReturn>
EXPLANATION:
The first template -- the Identity Template -- copies all nodes and attributes from the source XML document as-is.
The second template, which matches all elements with the specified, namespaced attribute equalling "true", effectively removes those elements.