根据映射条件合并 XML

Posted

技术标签:

【中文标题】根据映射条件合并 XML【英文标题】:Merge XMLs based on mapping condition 【发布时间】:2021-10-08 09:59:24 【问题描述】:

我正在寻找一种满足某些映射条件的合并 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 中很容易,在 XSLT 2 或 3 中更容易,您可以使用 key 函数,第三个参数是要搜索的文档。但是示例相当简单,不清楚是否总是只有第二个文档中根元素的两个子元素,或者如果有更多子元素和多个匹配项,如果你真的想合并所有数据,你想要哪种结构在一起。 @MartinHonnen 感谢您的意见。关于你的问题。第二个 XML 可以有 2 个以上的子元素。而且这里预计只有一个区块匹配。 看我的回答,应该可以解决的。 【参考方案1】:

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>

第一个文档是为了示例的自包含而内联的,但当然可以将其声明为 &lt;xsl:param name="key-doc" select="doc('xml1.xml')"/&gt;

即使在 XSLT 1 中,也无需使用密钥并使用例如&lt;xsl:param name="key-doc" select="document('xml1.xml')"/&gt;你可以直接选择

  <xsl:template match="/*">
      <xsl:copy>
          <xsl:copy-of select="*[key = $key-doc/root/key]/*"/>
      </xsl:copy>
  </xsl:template>

找到匹配的元素并将其子元素复制到输出。

【讨论】:

谢谢。我将对此进行测试。您建议使用哪种 XSLT 实现? JAXP 或撒克逊或其他什么? .我正在寻找开源实现。除了上述之外,我还有一些复杂的递归映射要完成,在基于映射键的相同 XML 块内 @amuru 使用 Saxon,它将为您提供最新的 XSLT 功能。 @amuru,在 Java 世界中,通常很容易使用 Saxon 10 或 9 来支持 XSLT 3 或 2,而不是 JRE 内置、基于 Xalan 的 XSLT 1 处理器。 @MartinHonnen 以上 xsl 为我工作。有没有办法在'key'函数中为'select;'引用变量? ?我正在尝试进行递归映射。所以有一个变量引用 xml 元素块。我想使用这个元素作为我选择下一个块的选择标准。你对此有什么想法吗 @amuru,我不清楚您的“递归”映射的新问题或扩展问题的外观如何。考虑提出一个包含所有必要细节的新问题。

以上是关于根据映射条件合并 XML的主要内容,如果未能解决你的问题,请参考以下文章

如何根据条件合并两个数据集

如何根据条件合并两个数据框?

根据两行的条件合并行? [复制]

pandas - 根据满足条件的列合并行

Python Pandas:如何根据“OR”条件进行合并?

根据 if 条件合并和求和两个 pandas 行