将xml(Freeplane应用程序)转换为json

时间:2017-01-13 10:48:56

标签: json xml xslt

我尝试使用xsl语法将一些xml文件(从Freeplane应用程序)转换为json;达到这样的结果:

[
    {"title": "Animalia", "children": [
        {"title": "Chordate", "children": [
            {"title": "Mammal", "children": [
                {"title": "Primate", "children": [
                    {"title": "Primate"},
                    {"title": "Carnivora"}
                ]},
                {"title": "Carnivora", "children": [
                    {"title": "Felidae"}
                ]}
            ]}
        ]},
        {"title": "Arthropoda", "children": [
            {"title": "Insect", "children": [
                {"title": "Diptera"}
            ]}
        ]}
    ]}
]

这是我的xsl文件:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no"/>
  <xsl:param name="indent-increment" select="'    '" />

  <xsl:template match="map">
    <!-- Ignores root 'node' -->
    <xsl:apply-templates select="node/node"/>
  </xsl:template>

  <xsl:template match="node">
    <xsl:param name="indent" select="'&#x0A;'"/>
    <xsl:variable name="indent0" select="$indent" />
    <xsl:variable name="indent1" select="concat($indent, $indent-increment)" />

    <xsl:if test="position() &gt; 1">, </xsl:if>

    <xsl:text>[</xsl:text>

    <xsl:value-of select="$indent1"/>
    <xsl:text>{"title": "</xsl:text>
    <!-- Need to replace " with \" in @TEXT strings -->
    <xsl:value-of disable-output-escaping='yes' select="@TEXT"/>
    <xsl:text>"</xsl:text>

    <!-- Recursion 
    <xsl:if test="@LINK">
      <xsl:text>,</xsl:text>
      <xsl:value-of select="$indent1"/>
      <xsl:text>url: "</xsl:text>
      <xsl:value-of disable-output-escaping='yes' select="@LINK"/>
      <xsl:text>"</xsl:text>
    </xsl:if>
    -->


    <xsl:if test="node">
      <xsl:text>,</xsl:text>
      <xsl:value-of select="$indent1"/>
      <xsl:text>"children": </xsl:text>

      <!-- Recursion -->
      <xsl:apply-templates select="node">
        <xsl:with-param name="indent" select="$indent1"/>
      </xsl:apply-templates>

      <xsl:text>}</xsl:text>
    </xsl:if>

      <xsl:if test="not(node)">
          <xsl:text>}</xsl:text>      
    </xsl:if>


    <xsl:value-of select="$indent"/>
    <xsl:text>]</xsl:text>

  </xsl:template>
</xsl:stylesheet>

我在xsl文件中尝试了很多组合但是我没有成功地使用正确的语法在最后有一个干净的json。 而我的json文件给了我这个(错误的)输出:

[
    {"title": "Animalia",
    "children": [
        {"title": "Chordate",
        "children": [
            {"title": "Mammal",
            "children": [
                {"title": "Primate",
                "children": [
                    {"title": "Carnivora",
                    "children": [
                        {"title": "Felidae"}
                    ]}
                ]}
            ]}
        ]}
    ], [
        {"title": "Arthropoda",
        "children": [
            {"title": "Insect",
            "children": [
                {"title": "Diptera"}
            ]}
        ]}
    ]}
]

我知道我的xsl文件是错误的但是在这一点上,我找不到合适的解决方案,所以如果有人知道如何将一个制作精良的xsl文件转换成我想要的json,我会很高兴...... 感谢

以下是Freemind应用程序生成的xml文件:

<map version="1.0.1">
<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->
<node CREATED="1484301934011" ID="ID_389012734" MODIFIED="1484301940301" TEXT="test">
<node CREATED="1484301961212" MODIFIED="1484301961212" POSITION="right" TEXT="Animalia">
<node CREATED="1484301961212" MODIFIED="1484301961212" TEXT="Chordate">
<node CREATED="1484301961213" MODIFIED="1484301961213" TEXT="Mammal">
<node CREATED="1484301961214" MODIFIED="1484301961214" TEXT="Primate">
<node CREATED="1484301961214" MODIFIED="1484301961214" TEXT="Carnivora">
<node CREATED="1484301961215" MODIFIED="1484301961215" TEXT="Felidae"/>
</node>
</node>
</node>
</node>
<node CREATED="1484301961216" MODIFIED="1484301961216" TEXT="Arthropoda">
<node CREATED="1484301961216" MODIFIED="1484301961216" TEXT="Insect">
<node CREATED="1484301961217" MODIFIED="1484301961217" TEXT="Diptera"/>
</node>
</node>
</node>
</node>
</map>

1 个答案:

答案 0 :(得分:1)

看看xsltjson,它可能完全按照你想要的那样做,但如果没有,你可以调整它以获得输出

更新:

鉴于您的XML,您正在转换数据并将其转换为json。我建议你将这些操作分开处理,将XML转换为套件然后将其转换为json的格式。我建议使用现有的库来进行XML到JSON的转换,因为它很繁琐,而自制的解决方案很可能是错误的。

我建议您将XML转换为类似

的内容
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Liquid Studio 2017 - Developer Bundle Edition (Trial) 15.0.0.7084 (https://www.liquid-technologies.com) -->
<children>
    <title>test</title>
    <children xmlns:json="http://json.org/" json:force-array="true">
        <title>Animalia</title>
        <children json:force-array="true">
            <title>Chordate</title>
            <children json:force-array="true">
                <title>Mammal</title>
                <children json:force-array="true">
                    <title>Primate</title>
                    <children json:force-array="true">
                        <title>Carnivora</title>
                        <children json:force-array="true">
                            <title>Felidae</title>
                        </children>
                    </children>
                </children>
            </children>
        </children>
        <children json:force-array="true">
            <title>Arthropoda</title>
            <children json:force-array="true">
                <title>Insect</title>
                <children json:force-array="true">
                    <title>Diptera</title>
                </children>
            </children>
        </children>
    </children>
</children>

然后使用xsltjson将其转换为json

{
    "": {
        "children": {
            "title": "test",
            "children": [
                {
                    "title": "Animalia",
                    "children": [
                        {
                            "title": "Chordate",
                            "children": [
                                {
                                    "title": "Mammal",
                                    "children": [
                                        {
                                            "title": "Primate",
                                            "children": [
                                                {
                                                    "title": "Carnivora",
                                                    "children": [
                                                        {
                                                            "title": "Felidae"
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "title": "Arthropoda",
                            "children": [
                                {
                                    "title": "Insect",
                                    "children": [
                                        {
                                            "title": "Diptera"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    }
}

这样的事情应该这样做

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:json="http://json.org/"
                 exclude-result-prefixes="xs xsl json">
    <xsl:include href="xml-to-json.xsl"></xsl:include>

    <xsl:template match="/">
        <xsl:variable name="myXml">
            <children>
                <xsl:apply-templates select="map/*"></xsl:apply-templates>
            </children>
        </xsl:variable>
        <xsl:value-of select="json:generate($myXml)"/>

    </xsl:template>

    <xsl:template match="node">
        <title>
            <xsl:value-of select="@TEXT"></xsl:value-of> 
        </title>
        <xsl:for-each select="node">
            <children json:force-array="true" xmlns:json="http://json.org/">
                <xsl:apply-templates select="."></xsl:apply-templates>
            </children>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>