Reputation: 2807
xslt 3.0 saxon PE 11.4
I've got this to work, but by accident.
Consider this input.
<?xml version="1.0" encoding="UTF-8"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet">
</Workbook>
and I want to get to this JSON (encodings are hard...so I think I NEED to escape the '"' char, and I'm not too worried about the JSON escaping of '/')
{
"xmlData": "<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"><\/Workbook>"
}
so basically some external psuedo code can go.
json = JSON.Read("file.json")
xmlString = json["xmlDate"]
xml = XDocument.Parse(xmlString)
and the xml is read into some xml model.
so my attempt is this.
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="map array">
<xsl:output method="json"/>
<xsl:template match="/">
<xsl:variable name="transformed-xml">
<xsl:copy-of select="."/>
</xsl:variable>
<xsl:map>
<xsl:map-entry key="'xmlData'" select="serialize($transformed-xml)"/>
</xsl:map>
</xsl:template>
</xsl:stylesheet>
1st try
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="map array">
<xsl:output method="json"/>
<xsl:template match="/">
<xsl:variable name="transformed-xml">
<xsl:copy-of select="."/>
</xsl:variable>
<xsl:variable name="json-string">
<!-- Convert the transformed XML to a JSON string -->
<xsl:value-of select="serialize($transformed-xml)"/>
</xsl:variable>
<xsl:map>
<xsl:map-entry key="'xmlData'" select="$json-string"/>
</xsl:map>
</xsl:template>
</xsl:stylesheet>
gives me this
{
"xmlData": "<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\">\n<\/Workbook>"
}
nasty...its 'xml' escaped the '<','>', and the new line...not 100% sure why, I assume serialise is escaping the string into 'xml' format, because its embedding a 'text' node inside a document-node?
ok...try 2
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="map array">
<xsl:output method="json"/>
<xsl:template match="/">
<xsl:variable name="transformed-xml">
<xsl:copy-of select="."/>
</xsl:variable>
<xsl:map>
<xsl:map-entry key="'xmlData'" select="serialize($transformed-xml)"/>
</xsl:map>
</xsl:template>
</xsl:stylesheet>
gives
{
"xmlData": "<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\">\n<\/Workbook>"
}
which works! because its not 1st embedding it in a text node inside a document node?
P.S. I assume this is a sensible way to do this that wont bite me later?
Upvotes: 0
Views: 74
Reputation: 167716
JSON output can serialize nodes so
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">
<xsl:output method="json" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select="map { 'xmlData' : . }"/>
</xsl:template>
</xsl:stylesheet>
gives e.g. (Saxon HE 12.3)
{ "xmlData":"<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\">\n<\/Workbook>" }
There is also a serialization attribute https://www.w3.org/TR/xslt-xquery-serialization-31/#JSON_JSON-NODE-OUTPUT-METHOD to control the node serialization method used for nodes serialized as part of the json output method.
So basically I am not sure why you attempt to serialize the XML in your own code.
Upvotes: 1