将Atom(XML)转换为JSON。

3

有没有办法将Atom(XML)格式的数据转换为JSON格式?我希望能找到一个免费的在线工具来完成这个任务。由于数据包含敏感信息,我无法在网上发布它。


你实际上想要什么格式?仅仅说“JSON”有点含糊,因为内部结构可能是完全不同的。 - cloudfeet
@cloudfeet 我希望JSON能够按照XML中提供的字段名称和结构进行格式化。只需要将Atom(XML)直接转换为JSON即可。 - Alexander Johansen
2个回答

5
"将XML转换为JSON"听起来很简单,但XML和JSON是不同的结构范例。如果您的XML文档如下所示:
<a>
    <b>foo</b>
    <c prop="value">bar</c>
</a>

如果有一个XML文档,你如何在JSON中表示它?有很多问题,比如:

  • 排序是否重要?(JSON中的对象属性是无序的,因此在转换后无法确定<c>是在<b>之前还是之后)
  • 如果只有一个<b>,这意味着它是单个项目数组还是仅仅是一个对象?
  • 如何表示属性?转换器是否根据定义属性来回切换纯字符串(对于"b")和带有额外属性的对象(对于"c")?

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

因此,为了得到完整的答案,我认为您需要清楚地了解您想要的JSON ATOM格式应该是什么样子的。


如果你只是想要某件东西,并且你可以适应任何你得到的东西,那么你可能可以使用像 Yahoo Pipes 这样的服务来实现此目的 (例如 这里, 我相信还有更多类似的服务)。然而,你会受到实际转换器的任性影响,这可能会导致奇怪的行为 (例如,有一天你的源提要添加了一个属性,你的输出会发生巨大变化)。

为了减少歧义,翻译器应该检查XML的Schema/DTD。 - Pablo Bianchi

1
我们在这里找到了一个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>

希望这能帮到您!

虽然此链接可能回答了问题,但最好包括答案的必要部分并提供该链接作为参考。仅有链接的答案可能会因链接页面变更而失效。 - bummi
感谢你也提供了我博客的网址 ;) - Bojan Bjelic
@BojanBjelic,不客气! :-) 那个XSLT对我们非常有用。 - Shinta Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接