【问题标题】:Convert Atom (XML) to JSON将 Atom (XML) 转换为 JSON
【发布时间】:2013-12-28 01:22:18
【问题描述】:

有人可以将数据从 Atom (XML) 格式转换为 JSON 吗?我更喜欢免费的在线工具来做到这一点。我无法发布我尝试在线转换的数据:因为它包含敏感信息。

【问题讨论】:

  • 您真正想要的格式是什么?只是说“JSON”会让事情有点模糊,因为内部结构绝对可以是任何东西。
  • @cloudfeet 我希望 JSON 在 XML 中提供的字段名称和结构之后进行格式化。只是从 Atom (XML) 到 JSON 的直接隐蔽。

标签: json xml converter atom-feed


【解决方案1】:

“将 XML 转换为 JSON”说起来简单,但 XML 和 JSON 是不同的结构范式。如果您的 XML 文档如下所示:

<a>
    <b>foo</b>
    <c prop="value">bar</c>
</a>

...您如何在 JSON 中表示它?有很多问题,例如:

  • 订购重要吗? (JSON 中的对象属性是无序的,因此转换后无法判断 &lt;c&gt; 是在 &lt;b&gt; 之前还是之后)
  • 如果只有一个&lt;b&gt;,这是否意味着它是一个单项数组,还是只是一个对象?
  • 如何表示属性?转换器是否会在纯字符串(对于"b")和具有额外属性的对象(对于"c")之间切换,这取决于是否定义了属性?

我见过的每个“XML 到 JSON 转换器”都采取了稍微不同的方法,因此没有可依赖的“标准”行为。

因此,为了获得完整的答案,我认为您需要更清楚地了解您希望 JSON ATOM 格式的外观。


如果你只是想要一些东西,并且你会解决你得到的任何东西,那么你可以使用 Yahoo Pipes 之类的服务来做到这一点(例如 here,我敢肯定还有更多)。

但是,您会随心所欲地在幕后使用任何实际的转换器,这可能会产生奇怪的行为(例如,有一天您的源提要添加了一个属性,并且您的输出发生了巨大变化)。

【讨论】:

  • 为减少歧义,此类翻译器应检查 XML 的 Schema/DTD。
【解决方案2】:

我们在这里找到了一个 XSLT:

http://www.bjelic.net/2012/08/01/coding/convert-xml-to-json-using-xslt/#code

并稍微修改它以将 Atom 文档的链接和类别元素处理为我们想要显示的方式。

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="utf-8"/>

    <xsl:template match="/*[node()]">
        <xsl:text>{</xsl:text>
        <xsl:apply-templates select="." mode="detect" />
        <xsl:text>}</xsl:text>
    </xsl:template>

    <xsl:template match="*" mode="detect">
        <xsl:choose>
            <xsl:when test="name(preceding-sibling::*[1]) = name(current()) and name(following-sibling::*[1]) != name(current())">
                    <xsl:apply-templates select="." mode="obj-content" />
                <xsl:text>]</xsl:text>
                <xsl:if test="count(following-sibling::*[name() != name(current())]) &gt; 0">, </xsl:if>
            </xsl:when>
            <xsl:when test="name(preceding-sibling::*[1]) = name(current())">
                    <xsl:apply-templates select="." mode="obj-content" />
                    <xsl:if test="name(following-sibling::*) = name(current())">, </xsl:if>
            </xsl:when>
            <xsl:when test="following-sibling::*[1][name() = name(current())]">
                <xsl:text>"</xsl:text><xsl:value-of select="name()"/><xsl:text>" : [</xsl:text>
                    <xsl:apply-templates select="." mode="obj-content" /><xsl:text>, </xsl:text>
            </xsl:when>
            <xsl:when test="count(./child::*) > 0 or count(@*) > 0">
                <xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : <xsl:apply-templates select="." mode="obj-content" />
                <xsl:if test="count(following-sibling::*) &gt; 0">, </xsl:if>
            </xsl:when>
            <xsl:when test="count(./child::*) = 0">
                <xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : "<xsl:apply-templates select="."/><xsl:text>"</xsl:text>
                <xsl:if test="count(following-sibling::*) &gt; 0">, </xsl:if>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="*" mode="obj-content">
        <xsl:text>{</xsl:text>
            <xsl:apply-templates select="@*" mode="attr" />
            <xsl:if test="count(@*) &gt; 0 and (count(child::*) &gt; 0 or text())">, </xsl:if>
            <xsl:apply-templates select="./*" mode="detect" />
            <xsl:if test="count(child::*) = 0 and text() and not(@*)">
                <xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : "<xsl:value-of select="text()"/><xsl:text>"</xsl:text>
            </xsl:if>
            <xsl:if test="count(child::*) = 0 and text() and @*">
                <xsl:text>"text" : "</xsl:text><xsl:value-of select="text()"/><xsl:text>"</xsl:text>
            </xsl:if>
        <xsl:text>}</xsl:text>
        <xsl:if test="position() &lt; last()">, </xsl:if>
    </xsl:template>

    <xsl:template match="@*" mode="attr">
        <xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : "<xsl:value-of select="."/><xsl:text>"</xsl:text>
        <xsl:if test="position() &lt; last()">,</xsl:if>
    </xsl:template>

    <xsl:template match="node/@TEXT | text()" name="removeBreaks">
        <xsl:param name="pText" select="normalize-space(.)"/>
        <xsl:choose>
            <xsl:when test="not(contains($pText, '&#xA;'))"><xsl:copy-of select="$pText"/></xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="concat(substring-before($pText, '&#xD;&#xA;'), ' ')"/>
                <xsl:call-template name="removeBreaks">
                    <xsl:with-param name="pText" select="substring-after($pText, '&#xD;&#xA;')"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

希望有帮助!

【讨论】:

  • 虽然此链接可能会回答问题,但最好包含答案here 的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
  • 为我的博客提供 URL 干杯 ;)
  • @BojanBjelic,欢迎您! :-) XSLT 对我们非常有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 2020-02-14
  • 1970-01-01
  • 1970-01-01
  • 2015-05-30
  • 2017-08-07
相关资源
最近更新 更多