将 XML 中的属性转换为 JSON
Transform atrribute in XML to JSON
我有一个 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"
}
}
这不是我所期望的,我想在元素 [=26= 中包含 name 属性]root 但忽略元素 jobCode 中的 name 属性。我的预期如下:
{
"root": {
"name": "test-root",
"id": "9876",
"jobCode": "1009"
}
}
如何自定义配置以获得此输出?谢谢!
我认为该选项没有您希望的那么先进。
在这种情况下,我会使用样式表来预处理我的 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,并一起删除忽略属性配置。
在您的原始文件中,两个名称属性都在未命名的命名空间中。
元素(而非属性)继承当前作用域的命名空间。
通过指定忽略所有属性 QName("name") 处理器正确地忽略了所有 "name" 属性。
我知道这不是你 'wanted' 但经过反思,它应该是你 'expect' ......即代码如何知道 root/@name 和 jobCode/@name 两者之间的区别name 属性是否相同 QName?
David (Ennis) 的方法是解决此类问题的推荐方法(之一)。 json:xxx 代码是一个方便的库,可以相当好且相当简单地解决常见用例,但作为一个妥协的 doent 可以简单地解决每个用例,如果有的话。
如果您的输入和输出 'almost but not quite',通常预转换然后 json:xxx 调用的组合很有用...然后有时只是问题案例的简单转换,然后是 json:xxx 库是一个合理的权衡。
特别是在 ML 8.0 及更高版本中,json:transform-from-xml() 的结果会生成原生 JSON 对象(不是字符串)。根据您的用例,这可能是一个显着差异——它不需要重新解析就可以变成原生 JSON。另一方面,它确实需要序列化才能变成字符串。
我有一个 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"
}
}
这不是我所期望的,我想在元素 [=26= 中包含 name 属性]root 但忽略元素 jobCode 中的 name 属性。我的预期如下:
{
"root": {
"name": "test-root",
"id": "9876",
"jobCode": "1009"
}
}
如何自定义配置以获得此输出?谢谢!
我认为该选项没有您希望的那么先进。
在这种情况下,我会使用样式表来预处理我的 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,并一起删除忽略属性配置。
在您的原始文件中,两个名称属性都在未命名的命名空间中。 元素(而非属性)继承当前作用域的命名空间。 通过指定忽略所有属性 QName("name") 处理器正确地忽略了所有 "name" 属性。 我知道这不是你 'wanted' 但经过反思,它应该是你 'expect' ......即代码如何知道 root/@name 和 jobCode/@name 两者之间的区别name 属性是否相同 QName?
David (Ennis) 的方法是解决此类问题的推荐方法(之一)。 json:xxx 代码是一个方便的库,可以相当好且相当简单地解决常见用例,但作为一个妥协的 doent 可以简单地解决每个用例,如果有的话。
如果您的输入和输出 'almost but not quite',通常预转换然后 json:xxx 调用的组合很有用...然后有时只是问题案例的简单转换,然后是 json:xxx 库是一个合理的权衡。
特别是在 ML 8.0 及更高版本中,json:transform-from-xml() 的结果会生成原生 JSON 对象(不是字符串)。根据您的用例,这可能是一个显着差异——它不需要重新解析就可以变成原生 JSON。另一方面,它确实需要序列化才能变成字符串。