将内存节点转换为 JSON

Transform memory nodes to JSON

我需要将 der 内存节点转换为 JSON。预期输出:

{
    "citations": [
        {
            "cited": "classes",
            "procceding": [
                "applied",
                "considered",
                "followed"
            ]
        },
        {
            "cited": "toCase",
            "procceding": [
                "Ty Corp Ltd v Nu Inc",
                "PY Arbitrage v Bank of WN"
            ]
        }
    ]
}

我的 XQuery:

let $nodes :=
<cases>
  <citations>
    <classes>
      <text>applied</text>
      <text>considered</text>
      <text>followed</text>
    </classes>
    <toCase>
      <text>Ty Corp Ltd v Nu Inc</text>
      <text>PY Arbitrage v Bank of WN</text>
    </toCase>
  </citations>
</cases>
return     
let $map := map:map()
let $p :=
    for $node in $nodes/citations/node()
    let $nodeName := local-name($node)
    let $c :=
      map:put($map, "citations", map:new(map:entry('cited', map:new(map:entry($nodeName, (for $value in $node/node() return $value/fn:string(.)) ))) )  )
    return $c
return xdmp:to-json($map)

$nodes 被错误转换:

{"citations": {"cited": {"toCase": ["Ty Corp Ltd v Nu Inc", "PY Arbitrage v Bank of WN"]}}

如何获得预期的 JSON?

let $nodes :=
  <cases>
    <citations>
      <classes>
        <text>applied</text>
        <text>considered</text>
        <text>followed</text>
      </classes>
      <toCase>
        <text>Ty Corp Ltd v Nu Inc</text>
        <text>PY Arbitrage v Bank of WN</text>
      </toCase>
    </citations>
  </cases>
return     

let $citations := 
  for $node in $nodes/citations/node()
  let $nodeName := local-name($node)
  return 
    map:new(( 
      map:entry('cited', $nodeName), 
      map:entry("procceding", for $value in $node/node() return $value/fn:string(.) )
    ))   
return 
  map:entry("citations", $citations) => xdmp:to-json() 

--) 您可以使用 json:object() 构建内存中 JSON 模型(相当于 XML 模式)并保留对象顺序。我重构并简化了我的 xml-to-json 模块之一,如下所示。它应该可以满足您的需求。

declare function local:marshal-json(
  $master-node as node()
) as item()
{
  let $master-object := json:object()
  let $_ :=
    for $child-node in $master-node/node()
    let $child-name := local-name($child-node)
    return
      map:put($master-object, $child-name,
          for $floor in $child-node/node() return local:floor-object($floor)
      )      
  return $master-object        
};

declare function local:floor-object(
  $child-node as node()  
) as item()
{
  let $floor-object := json:object()
  let $_ := map:put($floor-object, "cited", local-name($child-node))
  let $floor-values := json:array()
  let $_ :=
    for $gc in $child-node/node()
    return json:array-push($floor-values, $gc/fn:string(.))
  let $_ := map:put($floor-object, "procceding", $floor-values)  
  return
    $floor-object  
};

let $nodes :=
<cases>
  <citations>
    <classes>
      <text>applied</text>
      <text>considered</text>
      <text>followed</text>
    </classes>
    <toCase>
      <text>Ty Corp Ltd v Nu Inc</text>
      <text>PY Arbitrage v Bank of WN</text>
    </toCase>
  </citations>
</cases>
return 
  local:marshal-json($nodes)

--) 我不能反对你的设计。但我赞成这种精神。 您应该能够使用 similar 逻辑将 XML 转换为 JSON(参数未硬编码 JSON 名称)。

示例:转换

<investment>
    <entity>
        <name>XYZ</name>
    </entity>
    <bogus>encrypted</bogus>
    <property>
        <Canadian>
            <propertyType>eligible dividend of CPC</propertyType>
            <notionalAmount>10000</notionalAmount>
        </Canadian>
        <foreign>
            <propertyType>dividend of trust</propertyType>
            <notionalAmount>7000</notionalAmount>
            <foreignWithholding>660</foreignWithholding>
        </foreign>
    </property>
    <capital>
        <portfolio>
            <name>HF25</name>
            <inadequateConsiderationFMV>10000</inadequateConsiderationFMV>
            <transferredAmount>15000</transferredAmount>
            <gainLossOnDisposition>11000</gainLossOnDisposition>
        </portfolio>
        <portfolio>
            <name>UL1</name>
            <superficialLoss>17000</superficialLoss>
            <reacquired>5000</reacquired>
            <gainLossOnDisposition>-2000</gainLossOnDisposition>
        </portfolio>
        <security-CUSIP1>
            <gainLossOnDisposition>-3600</gainLossOnDisposition>
        </security-CUSIP1>
    </capital>
</investment>

到JSON:

{
    "entity": {
        "name": "XYZ"
    },
    "bogus": null,
    "property": {
        "Canadian": {
            "propertyType": "eligible dividend of CPC",
            "notionalAmount": 10000
       },
        "foreign": {
            "propertyType": "dividend of trust",
            "notionalAmount": 7000,
            "foreignWithholding": 660
        }
    },
    "capital": {
        "portfolio": [
            {
                "name": "HF25",
                "inadequateConsiderationFMV": 10000,
                "transferredAmount": 15000,
                "gainLossOnDisposition": 11000
            },
            {
                "name": "UL1",
                "superficialLoss": 17000,
                "reacquired": 5000,
                "gainLossOnDisposition": -2000
            }
        ], 
        "security-CUSIP1": {
            "gainLossOnDisposition": -3600
        }
    }
}

我使用具有更多影响力的低级 API:它根据指令将 XML string/text 转换为 JSON stringnumber;符合自定义的JSON模型、对象和数组结构;它遵守金融领域的 XML/JSON 命名约定。

--) 也就是说,这种编程模型是内存密集型的。如果 XSLT3 在 Java 的流模型中解析和转换 JSON,它可能会更节省内存。我从来没有像现在这样使用 XSLT3 JSON 解析器,因此无法评论它的功效。