1

我能够使用 XSLT 3.0 将 JSON 转换为 XML。转换为 XML 字段时,主题中的数据缺少 XML 结构。

{
  "student" : "john",
  "class" : "Bachelors",
  "subjects" : "<college><subject><subjects>maths</subjects><term>spring</term></subject></college>"
}

XSLT:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/> 
  <xsl:strip-space elements="*"/>
  <xsl:param name="jsonText"/>

  <xsl:template match="@*|node()"> 
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template> 

  <xsl:template name="init">
    <xsl:apply-templates select="json-to-xml($jsonText)"/> 
  </xsl:template>
</xsl:stylesheet>`

Java 代码:

public static void main(String[] args){
    final String XSLT_PATH = "src/so/test1/json2xml.xsl";
    final String JSON = ""{\n" +"    \"student\": \"john\",\n" +
    "    \"class\": \"Bachelors\"\n" +
    "    \"subjects\": \"<college><subject><subjects>maths</subjects><term>spring</term></subject></college>"\n"
                "}";

    OutputStream outputStream = System.out;    
    Processor processor = new Processor(false);    
    Serializer serializer = processor.newSerializer();
    serializer.setOutputStream(outputStream);    
    XsltCompiler compiler = processor.newXsltCompiler();
    XsltExecutable executable = compiler.compile(new StreamSource(new File(XSLT_PATH)));    
    XsltTransformer transformer = executable.load();
    transformer.setInitialTemplate(new QName("init")); 
    transformer.setParameter(new QName("jsonText"), new 
 XdmAtomicValue(JSON));
    transformer.setDestination(serializer);
    transformer.transform();
}

错误:

Error at char 12 in xsl:apply-templates/@select on line 8 column 58 of json2xml.xsl:
  FOJS0001: Invalid JSON input: Unescaped control character (xd)
Exception in thread "main" net.sf.saxon.s9api.SaxonApiException: Invalid JSON input: Unescaped control character (xd)
      at net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:599)
      at com.xmltojson.sampleclass.SimpleJaxp.main(SimpleJaxp.java:49)
Caused by: net.sf.saxon.trans.XPathException: Invalid JSON input: Unescaped control character (xd)
4

1 回答 1

2

添加模板

<xsl:template match="string[@key = 'subjects']" xpath-default-namespace="http://www.w3.org/2005/xpath-functions">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:sequence select="parse-xml(.)/node()"/>
  </xsl:copy>
</xsl:template>

确保将字符串数据解析为 XML。

请注意,使用 XSLT 3.0 您可以使用<xsl:mode on-no-match="shallow-copy"/>而不必拼出身份转换。

一个简单的例子是

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:param name="jsonText"><![CDATA[{
    "student" : "john",
    "class" : "Bachelors",
    "subjects" : "<college><subject><subjects>maths</subjects><term>spring</term></subject></college>"
    }]]></xsl:param>
    <xsl:mode on-no-match="shallow-copy"/>
    <xsl:template name="init">
        <xsl:apply-templates select="json-to-xml($jsonText)"/>
    </xsl:template>

    <xsl:template match="string[@key = 'subjects']" xpath-default-namespace="http://www.w3.org/2005/xpath-functions">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:sequence select="parse-xml(.)/node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

(当与 Saxon 9.8.0.3 HE 一起运行时it:init)输出

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
   <string key="student">john</string>
   <string key="class">Bachelors</string>
   <string key="subjects">
      <college xmlns="">
         <subject>
            <subjects>maths</subjects>
            <term>spring</term>
         </subject>
      </college>
   </string>
</map>

这是一个基于您在各种编辑中发布的代码片段的完整 Java 程序:

import java.io.File;
import java.io.OutputStream;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.Serializer;
import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.XsltCompiler;
import net.sf.saxon.s9api.XsltExecutable;
import net.sf.saxon.s9api.XsltTransformer;

public class Saxon98HETest1 {

    public static void main(String[] args) throws SaxonApiException {
        final String XSLT_PATH = "sheet1.xsl";
        String JSON = "{\n" +
"  \"student\" : \"john\",\n" +
"  \"class\" : \"Bachelors\",\n" +
"  \"subjects\" : \"<college><subject><subjects>maths</subjects><term>spring</term></subject></college>\"\n" +
"}";
        testJsonToXml(XSLT_PATH, JSON);
        System.out.println();

        JSON = "{\n" +
                            "    \"color\": \"red\",\n" +
                            "    \"value\": \"#f00\"\n" +
                            "}";
        testJsonToXml(XSLT_PATH, JSON);
        System.out.println();
    }

    static void testJsonToXml(String xsl, String json) throws SaxonApiException {
        OutputStream outputStream = System.out;
        Processor processor = new Processor(false);
        Serializer serializer = processor.newSerializer();
        serializer.setOutputStream(outputStream);
        XsltCompiler compiler = processor.newXsltCompiler();
        XsltExecutable executable = compiler.compile(new StreamSource(new File(xsl)));
        XsltTransformer transformer = executable.load();
        transformer.setInitialTemplate(new QName("init"));
        transformer.setParameter(new QName("jsonText"), new XdmAtomicValue(json));
        transformer.setDestination(serializer);
        transformer.transform();       
    }

}

当针对 Saxon 9.8.0.3 HE 编译和运行时,我得到了输出

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
   <string key="student">john</string>
   <string key="class">Bachelors</string>
   <string key="subjects">
      <college xmlns="">
         <subject>
            <subjects>maths</subjects>
            <term>spring</term>
         </subject>
      </college>
   </string>
</map>

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
   <string key="color">red</string>
   <string key="value">#f00</string>
</map>

并且没有错误。样式表如上图,没有预设参数内容:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:param name="jsonText"></xsl:param>
    <xsl:mode on-no-match="shallow-copy"/>
    <xsl:template name="init">
        <xsl:apply-templates select="json-to-xml($jsonText)"/>
    </xsl:template>

    <xsl:template match="string[@key = 'subjects']" xpath-default-namespace="http://www.w3.org/2005/xpath-functions">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:sequence select="parse-xml(.)/node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
于 2017-07-24T15:26:38.437 回答