如何查询由 json-to-xml 生成的 XML 文档节点
How to query a XML document-node produced by json-to-xml
我希望导入 JSON 数据以使用 XSLT 进行处理并获得结果 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>
如果你想展平一些你通常处理的结构 //*
或者在那种情况下只处理叶元素 //*[@key and not(*)]
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:root="http://www.example.org/1"
xmlns:flat="http://www.example.org/2"
exclude-result-prefixes="xs"
expand-text="yes">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="data">
<root:report>
<xsl:apply-templates select="json-to-xml(.)//*[@key and not(*)]"/>
</root:report>
</xsl:template>
<xsl:template match="*[@key]">
<xsl:element name="flat:{@key}">
<xsl:attribute name="contextRef">period0</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
为了产生你想要的结果,我不认为我会使用 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 的回答的评论中看到你简化了实际问题,但我认为这种方法应该证明具有足够的可扩展性。
我希望导入 JSON 数据以使用 XSLT 进行处理并获得结果 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>
如果你想展平一些你通常处理的结构 //*
或者在那种情况下只处理叶元素 //*[@key and not(*)]
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:root="http://www.example.org/1"
xmlns:flat="http://www.example.org/2"
exclude-result-prefixes="xs"
expand-text="yes">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="data">
<root:report>
<xsl:apply-templates select="json-to-xml(.)//*[@key and not(*)]"/>
</root:report>
</xsl:template>
<xsl:template match="*[@key]">
<xsl:element name="flat:{@key}">
<xsl:attribute name="contextRef">period0</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
为了产生你想要的结果,我不认为我会使用 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 的回答的评论中看到你简化了实际问题,但我认为这种方法应该证明具有足够的可扩展性。