xslt转换为json

时间:2014-12-22 16:05:53

标签: xml json xslt xslt-1.0

输入我得到了:

  <table>   
    <source1>
      <ptr>
          <data name="text1">20431</data>
          <data name="text2">collins</data>
          <data name="text3">20141231></data>
          <data name="text4">regard</data>
      </ptr>
    </source1>
    <source2>
        <ptr>
            <data name="note1">C</data>
            <data name="note2">A</data>
            <data name="note3">22356</data>
            <data name="note4">465506</data>
            <data name="note5">434562491057912</data>
            <data name="note6">milk</data>
            <data name="note7">dfRTA</data>
        </ptr>
    </source2>
    <source3>
    <enroll>n</enroll>
    </source3>
    </table>

需要将此转换为json为

{
"table":
{
"source1":
{"text1":"20431",
"text2": "collins",
"text3": "20141231",
"text4" :"regard"
},
"source2":
{"note1":"20431",
"note2": "A",
"note3":"22356",
"note4":"465506",
"note5":"434562491057912",
"note6":"milk",
"note7":"dfRTA"
}
}}

如何使用xsl转换任何通用的,而不是在每个属性名称上进行匹配。 任何人都有将进行上述转换的样式表

1 个答案:

答案 0 :(得分:1)

正如评论中已经提到的,XSLT is generally the wrong tool to produce JSON。但是,如果您已经检查了所提供的链接,并且仍然想测试它是否适合您的要求或其他原因,那么在XSLT之后生成一个文本文件,对于您的示例输入XML,它是有效的JSON格式:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" doctype-public="XSLT-compat" 
     omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
  <xsl:template match="table">
    <xsl:text>{ "table" : {</xsl:text>
    <xsl:apply-templates/>
    <xsl:text>}}</xsl:text>
  </xsl:template>
  <xsl:template match="*[starts-with(local-name(),'source') and .//data]">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="local-name()"/>
    <xsl:text>" :</xsl:text>
    <xsl:text>{</xsl:text>
    <xsl:apply-templates select="@*|node()"/>
    <xsl:text>}</xsl:text>
    <xsl:if test="following-sibling::*[starts-with(local-name(),'source') 
                                            and .//data]">
        <xsl:text>, </xsl:text>
    </xsl:if>
  </xsl:template>
  <xsl:template match="data">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="@name"/>
    <xsl:text>" : "</xsl:text>
    <xsl:value-of select="."/>
    <xsl:text>"</xsl:text>
    <xsl:if test="following-sibling::data">
        <xsl:text>, </xsl:text>
    </xsl:if>
  </xsl:template>
  <xsl:template match="*[starts-with(local-name(),'source') 
                              and not(.//data)]"/>
</xsl:transform>

当应用于您的输入时,XML会产生以下输出:

{ "table" : {   
"source1" :{

      "text1" : "20431", 
      "text2" : "collins", 
      "text3" : "20141231>", 
      "text4" : "regard"
}, 
"source2" :{

        "note1" : "C", 
        "note2" : "A", 
        "note3" : "22356", 
        "note4" : "465506", 
        "note5" : "434562491057912", 
        "note6" : "milk", 
        "note7" : "dfRTA"
}
}}

虽然输入中并不完全清楚,但您提到需要转换所有数据元素的注释,因此我排除了名称以source开头并且没有名称为{{1的子节点的每个父元素(示例中为data)并在末尾应用了一个空模板以将其从输出中删除。
请注意,对于性能,可以改进检查source3节点是否包含任何source节点的表达式,具体取决于输入 - 例如如果已知包含data的来源始终包含在data中,则最好将匹配模式调整为ptr<xsl:template match="*[starts-with(local-name(),'source') and .//data]">(或<xsl:template match="*[starts-with(local-name(),'source') and ptr]">可能会出现空ptr/data个元素。) 如果您想从输出中删除不必要的空格,可以在ptr下方添加<xsl:strip-space elements="*"/>,以便将结果文本/“JSON”放在一行中。