如何查询由 json-to-xml 生成的 XML 文档节点

问题描述

我希望导入要使用 XSLT 处理的 JSON 数据并获得结果 XML。我确实理解“json-to-xml”所做的解析意味着由其他映射、数组、键和值组成的映射的结果。我不遵循的是应该使用什么语法来查询地图。似乎第一步总是从 JSON 文件解析根级别的完整标签内容。我假设在解析“json-to-xml”之后的任何进一步查询都是针对文档生成节点进行的。

在下面的示例中,我从一个具有层次结构的 JSON 文件开始,但最终结果应该几乎是完全平坦的。 “通用”和“单元定义”(在 JSON 文件中)应用作有关如何转换数据的指导,例如使用哪个属性,但 JSON 中该级别的键不应出现在 XML 结果中。

我已经阅读了“json-to-xml”方面的 XSL 3.0 规范,但我没有找到任何针对生成的文档节点的查询示例。 https://www.w3.org/TR/xslt-30/#func-json-to-xml

还可以在此处找到以下代码https://xsltfiddle.liberty-development.net/jxWZS6Y/1

澄清问题:如何查询 json-to-xml 生成的映射,以获得低于“想要的结果”?

我的尝试:

XML 数据源文件

<data>
{
    "general": {
      "Language": "English","Country": "Sweden"
    },"units-deFinitions": {
      "SEK": "iso4217:SEK"
    }
  }
</data>

XSL:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
    xmlns:root="http://www.example.org/1"
    xmlns:flat="http://www.example.org/2"
>

  <xsl:output method="html" indent="yes" html-version="5"/>

  <xsl:template match="data">
      <!-- New root tag name -->
      <root:report>
          <xsl:apply-templates select="json-to-xml(.)"/>
      </root:report>
  </xsl:template>
  
  <xsl:template
  match="*[@key]"
  xpath-default-namespace="http://www.w3.org/2005/xpath-functions"
>
    <xsl:element name="flat:{@key}">
      <xsl:attribute name="contextRef">period0</xsl:attribute>
        <xsl:apply-templates/>
    </xsl:element>

</xsl:template>
  
</xsl:stylesheet>

结果:

<!DOCTYPE HTML>
<root:report xmlns:root="http://www.example.org/1" xmlns:flat="http://www.example.org/2">
   <flat:general contextRef="period0">
      <flat:Language contextRef="period0">English</flat:Language>
      <flat:Country contextRef="period0">Sweden</flat:Country>
   </flat:general>
   <flat:units-deFinitions contextRef="period0">
      <flat:SEK contextRef="period0">iso4217:SEK</flat:SEK>
   </flat:units-deFinitions>
</root:report>

想要的结果:

<?xml version="1.0" encoding="UTF-8"?>

<root:report
  xmlns:root="http://www.example.org/1"
  xmlns:flat="http://www.example.org/2"
  >
      <flat:Language contextRef="period0">English</base:Language>
      <flat:Country contextRef="period0">Sweden</base:Country>
      <flat:SEK contextRef="balance0">iso4217:SEK</base:SEK>
</root:report>

解决方法

为了产生您想要的结果,我不认为我会使用 json-to-xml(),我会直接处理 JSON。类似的东西:

<xsl:template match="data">
    <root:report>
      <xsl:variable name="json" select="parse-json(.)"/>
      <flat:Language contextRef="period0">{?general?Language}</flat:Language>
      <flat:Country contextRef="period0">{?general?Country}</flat:Country>
      <flat:SEK contextRef="period0">{?units-definitions?SEK}</flat:SEK>
    </root:report>
</xsl:template>

我从您对 @MartinHonnen 的回答的评论中看出,您已经简化了实际问题,但我认为这种方法应该具有足够的可扩展性。

,

如果你想扁平化一些结构,你通常会处理 $ python -c 'f = open("hello.bin","wb");f.write(b"hello");f.close()' $ xxd hello.bin 00000000: 6865 6c6c 6f hello $ python -c 'f = open("hello.bin","ab");f.write(b"\x00" * 32);f.close()' $ xxd hello.bin 00000000: 6865 6c6c 6f00 0000 0000 0000 0000 0000 hello........... 00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000020: 0000 0000 00 ..... 或者在这种情况下只处理叶元素 //*

//*[@key and not(*)]