XSLT合并2个XML文件

时间:2012-07-26 08:20:28

标签: xml xslt merge union

我知道这里有很少的xml / xslt合并相关问题但是似乎没有一个能解决我的问题。

我正在寻找的是一个XSLT(尽可能通用 - 与输入XML文件的结构不紧密),

将a.xml与b.xml合并,并以

的方式生成c.xml
  • c.xml将包含a.xml和b.xml之间的公共节点(与节点一起使用) 从a.xml获取的值)
  • 另外c.xml将包含b.xml中存在但不存在于a.xml中的节点(和值)

例如:合并 a.xml

<root_node>
  <settings>
    <setting1>a1</setting1>
    <setting2>a2</setting2>
    <setting3>
      <setting31>a3</setting31>
    </setting3>
    <setting4>a4</setting4>
  </settings>
</root_node>

b.xml

<root_node>
  <settings>
    <setting1>b1</setting1>
    <setting2>b2</setting2>
    <setting3>
      <setting31>b3</setting31>
    </setting3>
    <setting5 id="77">b5</setting5>
  </settings>
</root_node>

将生成 c.xml

<root_node>
  <settings>
  <setting1>a1</setting1>
  <setting2>a2</setting2>
  <setting3>
    <setting31>a3</setting31>
  </setting3>
  <setting5 id="77">b5</setting5>
</settings>

其他信息

我将尝试通过“公共节点”解释我理解的内容。这可能不是一个准确的xml / xslt定义 因为我不是任何专家。

a / root_node / settings / setting1 b / root_node / settings / setting1的“公共节点”因为使用相同的路径到达了2个节点。对于setting2和setting3也是如此。

2个“非公共节点”是 a / root_node / settings / setting4 ,只能在a.xml中找到 (它不应该出现在输出中)和 b / root_node / settings / setting5 ,它只能在b.xml中找到(它应该进入输出)。

通过“通用解决方案”我并不意味着可以使用任何输入XML格式的东西。我的意思是xslt不应该包含硬代码xpath,而你可能会添加限制,例如“只有在a.xml中的节点是唯一的时才能工作”或其他任何其他限制 限制你可能认为它是合适的。

2 个答案:

答案 0 :(得分:2)

对多个文件进行操作的基本技术是通过document()函数。文档功能如下所示:

<xsl:variable name="var1" select="document('http://example.com/file1.xml', /)"/>
<xsl:variable name="var2" select="document('http://example.com/file2.xml', /)"/>

获得这两份文件后,您可以使用他们在同一文档中提供的内容。

答案 1 :(得分:2)

以下XSLT 1.0程序可以满足您的需求。

将其应用于b.xml并将a.xml的路径作为参数传递。

以下是它的工作原理。

  1. 它遍历B,因为它包含您要保留的新节点以及AB之间的公共元素
    1. 我将“common element”定义为具有相同简单路径的任何元素。
    2. 我将“simple path”定义为斜线分隔的祖先元素名称列表和元素本身,即ancestor-or-self轴。
      因此,在您的示例B中,<setting31>将拥有root_node/settings/setting3/setting31/简单路径
    3. 请注意,此路径不明确。这意味着您不能在输入中同时拥有任何两个共享同一父级的元素。根据你的样本,我认为情况并非如此。
  2. 对于每个叶文本节点(元素中没有其他子元素的任何文本节点)
    1. 简单路径使用名为calculatePath的模板计算。
    2. 调用递归模板nodeValueByPath,尝试从其他文档中检索相应简单路径的文本值。
    3. 如果找到相应的文本节点,则使用其值。这满足了你的第一个要点。
    4. 如果未找到相应的节点,则使用手头的值,即B的值。这满足了你的第二个要点。
  3. 因此,新文档与B的结构相匹配,并包含:

    • 来自B的{​​{1}}中没有对应节点的所有文本节点值。
    • A中的相应节点存在时,
    • 来自A的文本节点值。

    这是XSLT:

    B