【问题标题】:Transform atrribute in XML to JSON将 XML 中的属性转换为 JSON
【发布时间】:2016-08-09 20:48:32
【问题描述】:

我有一个 XML 文档,想将它转换成 JSON 字符串:

<?xml  version="1.0" encoding="UTF-8"?>
<root name="test-root">
<id lang="en">9876</id>
<jobCode name="Teacher" xmlns:teacher="http://example.com/ns/teacher">1009</jobCode>
</root>

我使用这个自定义配置来做到这一点:

let $config := json:config("custom")     
let $_ := map:put( $config, "whitespace", "ignore" )
let $_ := map:put( $config, "ignore-attribute-names",(xs:QName("name"),xs:QName("lang")) )
return json:transform-to-json( fn:doc("/test1.xml"),$config)

下面是这个脚本的输出:

{
    "root": {
        "id": "9876", 
        "jobCode": "1009"
    }
}

这不是我所期望的,我想在元素 root 中包含 name 属性但忽略jobCode 元素中的 name 属性。我的预期如下:

{
    "root": {
        "name": "test-root",
        "id": "9876", 
        "jobCode": "1009"
    }
}

如何自定义配置以获得此输出?谢谢!

【问题讨论】:

    标签: json xml marklogic


    【解决方案1】:

    我认为该选项没有您希望的那么先进。

    在这种情况下,我会使用样式表来预处理我的 XML 以对其进行更多处理。这是一个工作示例:

      xquery version "1.0-ml";
    import module namespace json="http://marklogic.com/xdmp/json"
     at "/MarkLogic/json/json.xqy";
    
    
    let $xml := <root name="test-root">
    <id lang="en">9876</id>
    <jobCode name="Teacher"    xmlns:teacher="http://example.com/ns/teacher">1009</jobCode>
    </root>
    
    let $template := <xsl:stylesheet version="1.0"     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@name[name(./..) = 'jobCode']" />
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    </xsl:stylesheet>
    
    let $filtered-xml := xdmp:xslt-eval($template, $xml)
    
    let $config := json:config("custom")     
    let $_ := map:put( $config, "whitespace", "ignore" )
    let $_ := map:put( $config, "ignore-attribute-names",(xs:QName("lang")) )
    return json:transform-to-json( $filtered-xml,$config)
    

    结果:

    {
      "root": {
        "name": "test-root",
        "id": "9876",
        "jobCode": "1009"
      }
    }
    

    如果你走这条路,那么你也可以只匹配模板中的@lang,并一起删除 ignore-attribute 配置。

    【讨论】:

    • 这真是太棒了!谢谢!!!将 styleSheet 与 JSON API 相结合,我们可以进行更复杂的用户指定转换。
    • 是的,您还可以将您的 XML 直接转换为 json 转换代码的序列化版本(在安装目录中查找 ./Config/json.xsd 以供参考)。这没有任何想象空间,您可以获得您想要的确切结果。还要了解,如果您的 XML 有一个 xsd,那么转换器将尽力一开始就尽力而为(但这不会解决您的挑战)。如果原始答案/示例确实是您可以接受的解决方案,请标记答案以反映这一点。
    【解决方案2】:

    在您的原始文件中,两个名称属性都在未命名的命名空间中。 元素,但不是属性,继承当前范围的命名空间。 通过指定忽略所有属性 QName("name") 处理器正确地忽略了所有“name”属性。 我知道这不是您“想要”的,但经过反思,它应该是您“期望”的……即当两个名称属性都是相同的 QName?

    David (Ennis) 的方法是解决此类问题的推荐方法之一。 json:xxx 代码是一个方便的库,可以相当好且相当简单地解决常见用例,但作为一种妥协,它并没有简单地解决每个用例,如果有的话。

    如果您的输入和输出“几乎但不完全”,通常是预转换然后 json:xxx 调用的组合很有用......然后有时对 json:xxx 库后跟的问题案例的简单转换是一个合理的权衡。

    特别是在 ML 8.0 及更高版本中,json:transform-from-xml() 的结果会生成一个原生 JSON 对象(不是字符串)。根据您的用例,这可能会有很大的不同——它不需要重新解析即可转换为原生 JSON。另一方面,它确实需要序列化才能变成字符串。

    【讨论】:

      猜你喜欢
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      • 2016-10-26
      • 2019-01-04
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      • 2011-06-18
      相关资源
      最近更新 更多