0

我需要使用 saxonjs 将 json 转换为 xml,我不知道如何将键与 xml 节点匹配,我正在寻找一些示例,它们都不适合我,这是我的代码

const issue = {
   id: 1,
   details: {
       type: 'urgent',
       description: 'Description of issue comes here',
       date: '2021-12-12',       
   }
};

saxonJS.transform({
        stylesheetLocation: './issue.sef.json',
        sourceType: 'json',
        sourceText: issue,
        destination: 'serialized',
    }, 'async').then(data => {
        fs.open('output.xml', 'w', function(err, fd) {
            fs.write(fd, data.principalResult, (err2, bytes) => {
                if(err2) {
                    console.log(err2);
                }
            });

        }); 

        res.status(200).send('Ok');
    })
    .catch(err => {
        console.log(err);
        res.status(500).send('error');
    });

这就是我想要实现的输出

<xml>
     <issue id="1">
        <description>
            <![CDATA[
                Description of issue comes here
            ]]>
        </description>
        <type>urgent</type>
        <date>2021-12-12</date>
     </issue>
</xml>

你能帮我看看 xslt 模板吗?

4

1 回答 1

2

您显示的输入是一个 JavaScript 对象,在 JSON 规范的严格语法规则中它不是 JSON。

所以我认为最好使用JSON.stringify创建 JSON 并将其传递给 XPath 3.1 函数parse-json来创建 JSON,或者使用 Saxon-JS 2.3 功能来获取 JSON 文本,只要确保你正确地JSON.stringify编辑了那个对象。

至于看起来很简单的示例 XSLT,为了 XSLT 的可读性,下面的示例仅使用带有 XSLT 源代码的 JavaScript 字符串并通过 Saxon API 运行它:

const SaxonJS = require("saxon-js");

const issue = {
   id: 1,
   details: {
       type: 'urgent',
       description: 'Description of issue comes here',
       date: '2021-12-12',       
   }
};

const xslt = `<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" expand-text="yes">
  <xsl:output indent="yes" cdata-section-elements="description"/>
  
  <xsl:template match=".">
   <xml>
    <issue id="{?id}">
      <description>{?details?description}</description>
      <type>{?details?type}</type>
      <date>{?details?date}</date>
    </issue>
   </xml>
  </xsl:template>
</xsl:stylesheet>`;
      

const result = SaxonJS.XPath.evaluate(`transform(map {
  'stylesheet-text' : $xslt,
  'initial-match-selection' : parse-json($json),
  'delivery-format' : 'serialized'
})?output`,
[],
{ params : 
    {
        json : JSON.stringify(issue),
        xslt : xslt
    }
});

当然,最后您可以先将 XSLT 编译为 SEF/JSON,然后按照您的尝试运行它。

为您提供一个使用两个不同模板和应用模板的示例 XSLT,以下内容不是使用内联代码处理嵌套对象/映射,而是将其处理到不同的模板:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" expand-text="yes" xmlns:map="http://www.w3.org/2005/xpath-functions/map" exclude-result-prefixes="#all">
  <xsl:output indent="yes" cdata-section-elements="description"/>
  
  <xsl:template match=".[. instance of map(*) and map:contains(., 'id')]">
   <xml>
    <issue id="{?id}">
      <xsl:apply-templates select="?details"/>
    </issue>
   </xml>
  </xsl:template>
  
  <xsl:template match=".[. instance of map(*) and map:contains(., 'description')]">      
    <description>{?description}</description>
    <type>{?type}</type>
    <date>{?date}</date>
  </xsl:template>
  
</xsl:stylesheet>
于 2021-12-20T08:56:53.633 回答