简体   繁体   English

将XML中的atrribute转换为JSON

[英]Transform atrribute in XML to JSON

I have a XML document and want to transform it into a JSON string: 我有一个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>

I use this custom config to do it: 我使用这个自定义配置来做到这一点:

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)

Below is the output of this script: 以下是此脚本的输出:

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

It is not what i expected, I want to include the name attribute in element root but ignore the name attribute in element jobCode . 这不是我所期望的,我想在元素根中包含name属性,但忽略元素jobCode中name属性。 what i expected is like below: 我期望的是如下:

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

How can I custom the config to get this output? 如何自定义配置以获得此输出? Thanks! 谢谢!

I don't believe the option is as advanced as you are hoping. 我不相信这个选项和你希望的一样先进。

In this case, I would use a stylesheet to pre-process my XML to massage it a bit more. 在这种情况下,我会使用样式表来预处理我的XML以对其进行更多的按摩。 Here's a working sample: 这是一个工作样本:

  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)

results: 结果:

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

And if you go this route, then you can also just match on the @lang in the template as well and remove the ignore-attribute config all-together. 如果你走这条路线,那么你也可以在模板中匹配@lang并同时删除ignore-attribute配置。

In your original, both the name attributes are in the unnamed namespace. 在原始文件中,两个名称属性都在未命名的命名空间中。 Elements, but not attributes, inherit the namespace of the current scope. 元素(但不是属性)继承当前范围的命名空间。 by specifying to ignore all attributes QName("name") the processor is correctly omitting all "name" attributes. 通过指定忽略所有属性QName(“name”),处理器正确地省略所有“name”属性。 I understand this is not what you 'wanted' but on reflection, it should be what you 'expect' ... ie how is the code to know the difference between root/@name and jobCode/@name when both name attributes are the same QName? 我知道这不是你想要的,但是在反思时,它应该是你所期望的......即,当两个名称属性都是时,代码如何知道root / @ name和jobCode / @ name之间的区别同样的QName?

David (Ennis)'s approach is (one of) the recommended approaches to this kind of problem. 大卫(恩尼斯)的方法是(一种)推荐的解决此类问题的方法。 The json:xxx code is a convenience library that addresses common use cases reasonably well and reasonably simply, but as a compromprise doent address every use case simply, if at all. json:xxx代码是一个便利库,它可以合理地简单地处理常见的用例,但是作为一个简单的解决方案,可以简单地解决每个用例,如果有的话。

Often a combination of pre-transformation then json:xxx calls is useful if your input is and output 'almost but not quite' ... Then sometimes a simple transformation of just the problem cases followed by the json:xxx library is a reasonable tradeoff. 如果您的输入输出“几乎但不完全”,那么通常预转换然后json:xxx调用的组合是有用的...然后有时只是简单地转换json:xxx库后面的问题情况是一个合理的权衡。

In particular in ML 8.0 and above the result of json:transform-from-xml() produces a native JSON Object (not a string). 特别是在ML 8.0及更高版本中,json的结果:transform-from-xml()生成一个本机JSON对象(不是字符串)。 Depending on your use case, this can be a significant difference -- it does not require re-parsing to turn into native JSON. 根据您的使用情况,这可能是一个显着差异 - 它不需要重新解析变成本机JSON。 On the other hand it does require serialization to turn into a string. 另一方面,它需要序列化才能变成字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM