xml - 根据映射条件合并 XML
问题描述
我正在寻找一种满足某些映射条件的合并 XML 的最佳方法
XML1:
<root>
<key>123<key>
</root>
XML2:
<root>
<base_node_1>
<key>123<key>
<data1>aaa</data1>
<data2>bbb</data2>
</base_node_1>
<base_node_2>
<key>456<key>
<data1>xxx</data1>
<data2>yyy</data2>
</base_node_2>
</root>
预期输出:
<root>
<key>123<key>
<data1>aaa</data1>
<data2>bbb</data2>
</root>
将 XML1 中的 'key' 匹配到 XML2 中的块。如果找到匹配,则将属性映射到最终输出 xml。
这里要注意的是 XML2 标签中的 'base_node' 可能会改变。大约有 100 个可能的标签。
使用 JAXB 将 XML 转换为 Java 对象并将它们映射到 Java 中是一种方法。但是考虑到第二个 xml - XML2 的结构,JAXB 看起来很复杂
有一个更好的方法吗?可能是基于 XPATH 的映射?
解决方案
XSLT 2 或 3:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="key-doc">
<root>
<key>123</key>
</root>
</xsl:param>
<xsl:key name="lookup" match="root/key" use="."/>
<xsl:output indent="yes"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:copy-of select="*[key('lookup', key, $key-doc)]/*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
第一个文档是为了示例的自包含而内联的,但当然可以声明为<xsl:param name="key-doc" select="doc('xml1.xml')"/>
。
即使在 XSLT 1 中,不使用键并使用例如<xsl:param name="key-doc" select="document('xml1.xml')"/>
,您也可以简单地选择
<xsl:template match="/*">
<xsl:copy>
<xsl:copy-of select="*[key = $key-doc/root/key]/*"/>
</xsl:copy>
</xsl:template>
找到匹配的元素并将其子元素复制到输出。
推荐阅读
- mysql - Spark MySql 连接器 Jar
- sql - 如何以特定格式转置 SQL 中的表?
- excel - 比较excel中的两列,并复制第二列底部的差异
- .net - C# JSON:反序列化 Web API 中枚举中的字符串?
- python - glob.glob 在读取多个 csv 文件时返回一个空列表
- typescript - 实现 webview 和处理回调
- domain-driven-design - XML 生成器类的 DDD 组件
- laravel - 如何使用租赁 laravel 从存储文件夹中获取图像
- javascript - 这个 jQuery 的 JavaScript 等价物是什么?
- r - 根据data.table中一列的值更改多列的值