XSLT whitespace control with text output - xslt

Using xsltproc, how can I output CDATA sections without surrounding space, if the formatter I need to use formats around CDATA like this by inserting space? No requirement to use xsl:text. I also tried xsl:value-of but could not figure out how to use CDATA in xsl:value-of. (I can delete the space around CDATA, but the formatter simply adds it back).
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent='no' />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:text>
<![CDATA[/*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
]]>
</xsl:text>
<xsl:text>
<![CDATA[/*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
]]>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Output
jonsmirl#ares:~/aosp/blogs/jonsmirl.github.io/xml$ xsltproc test.xsl test.xsl
/*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
/*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
jonsmirl#ares:~/aosp/blogs/jonsmirl.github.io/xml$
Desired output
jonsmirl#ares:~/aosp/blogs/jonsmirl.github.io/xml$ xsltproc test.xsl test.xsl
/*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
/*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
jonsmirl#ares:~/aosp/blogs/jonsmirl.github.io/xml$
This solution works, my mistake was in thinking the text needed to be inside CDATA to get the formatter to leave it alone.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent='no' />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:text>/*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
</xsl:text>
<xsl:text>/*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
</xsl:text>
</xsl:template>
</xsl:stylesheet>

This solution works, my mistake was in thinking the text needed to be inside CDATA to get the formatter to leave it alone.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent='no' />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:text>/*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
</xsl:text>
<xsl:text>/*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
</xsl:text>
</xsl:template>
</xsl:stylesheet>

Related

After upgrading saxon-he-10.5 JAR, facing issue in the transformation

I have two XSL file, one XSL importing another one ,
Not getting any value in the variable data. The variable data I am using below to get the attributes. Since the data is empty. Not getting values from it. is there anything wrong in this line <xsl:variable name="data" select="$header/sections/code[#key=$key]"/>
XSL 1 : Veichle.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="Motor.xsl"/>
<xsl:output omit-xml-declaration="yes" method="xml" />
<xsl:param name="key" select="'vita'"/>
</xsl:transform>
XSL 2: Motor.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f1="urn:hl7-org:v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cda="urn:hl7-org:v3"
xmlns:sdtc="urn:hl7-org:sdtc" xpath-default-namespace="http://hl7.org/fhir"
xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:lookup="http://lookup.data"
xmlns:uuid="java:java.util.UUID" exclude-result-prefixes="fn lookup uuid sdtc cda xsl xsi f1">
<xsl:import href="section.xsl"/>
<xsl:output omit-xml-declaration="yes" method="xml"/>
<xsl:param name="key" select="'results'"/>
<xsl:param name="mostRecent" select="false()"/>
<xsl:variable name="header">
</xsl:transform>
The expression $header/sections/code/[#key=$key] wasn't valid in XPath 1.0, 2.0 or 3.0. In XPath 3.1 it has a meaning (it returns an array), but it's not the meaning you think it has. As Martin explains, you probably intended $header/sections/code[#key=$key], but I don't know why your previous XSLT processor didn't flag an error.
In addition to the namespace issue pointed out in the comment, i.e. to set xpath-default-namespace="http://hl7.org/fhir" where you want to select elements from that namespace, the other error in your code is in the section $header/sections/code/[#key=$key] where you probably want $header/sections/code[#key=$key], i.e. a boolean predicate on the last step for the code elements.
If you really upgraded from XSLT 1 or 2 to Saxon 10, then I would think for older processors the expression you have should have given you an error and in XSLT 3 it would create a sequence of arrays with a boolean value.

how to configure wso2esb to use Saxon 9.8 HE

I'm trying to use the XSLT Mediator using XSLT version "3.0".but i can't use following XSLT transformation.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output version="1.0" encoding="UTF-8" omit-xml-declaration="yes" indent="true"/>
<xsl:variable name="data" select="//return => json-to-xml()"></xsl:variable>
<xsl:template match="/" xpath-default-namespace="http://www.w3.org/2005/xpath-functions">
<ns1:root xmlns:ns1="http://urldata.com/ns1">
<ns1:MessageData>
<xsl:value-of select="$data//boolean[#key = 'accountstatus']"/>
</ns1:MessageData>
<ns1:Code>
<xsl:value-of select="$data//map[#key = 'response']/string[#key = 'Code']"/>
</ns1:Code>
<!--- use this approach for everything you want to select ... -->
</ns1:root>
</xsl:template>
</xsl:stylesheet>
The error i'm getting is: net.sf.saxon.trans.LicenseException: Requested feature (XSLT 3.0) requires Saxon-PE
get Saxon-HE 9.8 using below URL
https://sourceforge.net/projects/saxon/files/Saxon-HE/9.8/
And download most downloaded version and put it below path to your esb configuration
wso2esb-4.9.0/lib/
and restart the service
XSLT 3.0 was supported in the commercial versions of Saxon while it was still under development, but support moved into the open source version Saxon-HE only when the W3C spec was finalised. Try a later version of Saxon - the current version is 10.3.

Extract XML Multiple Namespace with XSL

I have this XML with namespace and i need to extract on segment "NewDataSet"
I have a xsl code but it's not works
<?xml version="1.0" encoding="UTF-8"?>
<Listado_OrdenesResponse xmlns='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'>
<Listado_OrdenesResult>
<diffgr:diffgram xmlns:diffgr='urn:schemas-microsoft-com:xml-diffgram-v1' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'>
<NewDataSet xmlns=''>
<RowNum diffgr:id='RowNum1' msdata:rowOrder='0'>
<MATNR>10000101</MATNR> <AUFNR>731200000047</AUFNR>
<MENGE>385</MENGE>
<MEINS>G</MEINS>
</RowNum>
<RowNum diffgr:id='RowNum2' msdata:rowOrder='1'>
<MATNR>45000528</MATNR>
<AUFNR>731200000047</AUFNR>
<MENGE>540</MENGE>
<MEINS>KG</MEINS>
</RowNum>
</NewDataSet>
</diffgr:diffgram>
</Listado_OrdenesResult>
</Listado_OrdenesResponse>
I need to extract like this segment , NewDataSet.
<NewDataSet> <RowNum>
<MATNR>10000101</MATNR>
<AUFNR>731200000047</AUFNR>
</RowNum>
<RowNum>
<MATNR>45000528</MATNR>
<AUFNR>731200000047</AUFNR>
</RowNum>
</NewDataSet>
<!-- Need To Extract -->
I have this code but the return is not as expected.
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2018 (https://www.liquid-technologies.com) -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<xsl:template match="//NewDataSet">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
When I run the above XSL, I got this XML.
I will have the segment without namespace
<?xml version="1.0" encoding="UTF-8"?>
<RowNum xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
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"
diffgr:id="RowNum1"
msdata:rowOrder="0">
<MATNR>10000101</MATNR>
<AUFNR>731200000047</AUFNR>
<MENGE>385</MENGE>
<MEINS>G</MEINS>
</RowNum>
<RowNum xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
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"
diffgr:id="RowNum2"
msdata:rowOrder="1">
<MATNR>45000528</MATNR>
<AUFNR>731200000047</AUFNR>
<MENGE>540</MENGE>
<MEINS>KG</MEINS>
</RowNum>
Can you Help me?
In XSLT 2.0, use <xsl:copy-of select="XXXX" copy-namespaces='no'/>.
In XSLT 1.0 you need to use a variant of the identity template, copying elements using <xsl:element name="{local-name()}" namespace="namespace-uri()"/>.
Please don't ask XSLT questions without saying which version you are using, as many things are easier with XSLT 2.0 or 3.0!

How do I extract a field from this XML using XSLT 1.0?

I'm an XSLT newbie, and need to use XSLT to extract some fields from a trademark file from the US Patent and Trademark Office. Here's a very simplified copy of a typical file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Transaction xmlns:ns2="urn:us:gov:doc:uspto:trademark:status" xmlns="http://www.wipo.int/standards/XMLSchema/trademarks">
<TradeMarkTransactionBody>
<TransactionContentDetails>
<TransactionCode>National Trademark Information</TransactionCode>
<TransactionData>
<TradeMarkDetails>
<TradeMark>
<RegistrationOfficeCode>US</RegistrationOfficeCode>
<ApplicationNumber>74631225</ApplicationNumber>
<ApplicationDate>1995-02-07-05:00</ApplicationDate>
<RegistrationNumber>2178784</RegistrationNumber>
<RegistrationDate>1998-08-04-04:00</RegistrationDate>
<FilingPlace>US</FilingPlace>
<MarkCurrentStatusDate>2008-08-11-04:00</MarkCurrentStatusDate>
<WordMarkSpecification>
<MarkVerbalElementText>JAVA </MarkVerbalElementText>
</WordMarkSpecification>
</TradeMark>
</TradeMarkDetails>
</TransactionData>
</TransactionContentDetails>
</TradeMarkTransactionBody>
</Transaction>
I would like to be able to produce:
App number: 74631225
Here are a couple of my failed attempts; Attempt #1:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" />
<xsl:template match="/">
App number: <xsl:value-of select="/Transaction/TradeMarkTransactionBody/TransactionContentDetails/TransactionData/TradeMarkDetails/TradeMark/ApplicationNumber"/>
</xsl:template>
</xsl:stylesheet>
Produces only:
App number:
Attempt #2:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" />
<xsl:template match="/Transaction/TradeMarkTransactionBody/TransactionContentDetails/TransactionData/TradeMarkDetails/TradeMark">
App number: <xsl:value-of select="ApplicationNumber"/>
</xsl:template>
</xsl:stylesheet>
produces:
National Trademark Information
US
74631225
1995-02-07-05:00
2178784
1998-08-04-04:00
US
2008-08-11-04:00
JAVA
Any help would be appreciated. Once I get past this gate and have at least one field working, I hope I can get into the real substance of my project. If it matters, I'm using both MSXSL and Treebeard (which uses Saxon, I think) for my testing.
Your XSLT code is missing the namespace declaration. Check out the root element in your Xml document, it says this:
xmlns="http://www.wipo.int/standards/XMLSchema/trademarks"
That means, any of the elements in your Xml document are in that namespace.
In the XSLTs, on the other hand, you did not specify any namespace, which means that your XSLT processor looks for element names specified in the XSLT with the "blank namespace" - so e.g. Transaction mentioned in your XSLT is not the same element as Transaction (from the http://www.wipo.int/standards/XMLSchema/trademarks namespace) mentioned in your Xml document.
XSLT, or rather XPath, does not know the concept of a "default" (prefix-less) namespace, which is why you will have to assign some arbitrary prefix - say tm:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tm="http://www.wipo.int/standards/XMLSchema/trademarks">
<xsl:output method="text" encoding="utf-8" />
<xsl:template match="/">
App number: <xsl:value-of select="/tm:Transaction/tm:TradeMarkTransactionBody/tm:TransactionContentDetails/tm:TransactionData/tm:TradeMarkDetails/tm:TradeMark/tm:ApplicationNumber"/>
</xsl:template>
</xsl:stylesheet>
This should get you a step closer to what you are looking for. I can try this only in a few hours from now; if you need further assistance, please leave a comment and I'll check back on this question.

XSLT is converting my hex attributes to something else, how do I stop it?

I'm trying to transform one xml file to output another xml file, and I need the attribute "account" to be output identically to how it appears below. I have a bunch of these values in the file, most are not working.
For values of account like 0x0406 it is output as 0.0.06. But for values like 0x002d it leaves them alone and they come through the way I want.
Any ideas?
Initial XML:
<?xml version="1.0" encoding="UTF-8"?>
...
<foo account="0x0406" other-stuff="blah" something-name="blah again"/>
...
This is my xslt template:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://some-internal-thing/user">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>
...
<xsl:attribute name="account"><xsl:value-of select="#account"/></xsl:attribute>
...
The described problem cannot be reproduced.
I have run the following transformation with 10 different xslt processors (Msxml3, Msxml4, Msxml6, .NET XslTransform, .NET XslCompiledTransform, AltovaXml(for XSLT 1.01.0), Saxon6.5.4, Saxon 9.1.07, Saxon 9.1.07.NET and XML-SPY-XSLT2.0) and they all produce the same correct result.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://some-internal-thing/user">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:attribute name="account"><xsl:value-of select="#account"/></xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
when this transformation is performed on the following XML document:
<?xml version="1.0" encoding="UTF-8"?>
<foo account="0x0406" other-stuff="blah" something-name="blah again"/>
the expected, correct result is produced:
<foo account="0x0406" />
In case your XSLT processor is not one of these and you really get a wrong result, this is a bug and should be reported to the vendors.
Can you try to change the encoding ? For example "ASCII" instead of "UTF-8".