文件结构: File1.xml和File2.xml都具有相同的结构。
文件具有资源的列表/数组,每个资源具有代码的列表/数组。
每个代码都由“ id”属性唯一标识。
每个代码都有“ override”属性,用于指定覆盖规则。
如果override =“ true”,则可以将file1.xml中的代码元素替换为file2.xml中的代码元素。
我想使用xslt和以下规则将File1.xml与File2.xml合并
如果两个文件具有相同的资源名称(例如:“ resource1”),则可以合并其中的代码。
在合并操作期间,如果我们具有相同的“ id”值,则只有在override =“ true”时,才能将file1代码元素替换为file2代码元素。
<code id="1" field1="value11" field2="value12" override="true" />
<code id="1" field1="value71" field2="value72" override="true" />
For this the result should be
<code id="1" field1="value71" field2="value72" override="true" />
如果override =“ false”,那么我们不会替换代码元素。
为此,结果应该是
如果我们有不同的资源名称(例如:File1.xml中的resource2和File2.xml中的resource3),则可以将它们写在output.xml中,如下所示: 文件之间没有任何内容可以合并。
非常感谢您对我的问题表现出兴趣!!!
File1.xml
<resources>
<resource name="resource1">
<codes>
<code id="1" field1="value11" field2="value12" override="true" />
<code id="2" field1="value21" field2="value22" override="false" />
<code id="3" field1="value31" field2="value32" override="true" />
</codes>
</resource>
<resource name="resource2">
<codes>
<code id="1" field1="value11" field2="value12" override="true" />
</codes>
</resource>
</resources>
File2.xml
<resources>
<resource name="resource1">
<codes>
<code id="1" field1="value71" field2="value72" override="true" />
<code id="2" field1="value81" field2="value82" override="true" />
<code id="4" field1="value91" field2="value92" override="true" />
</codes>
</resource>
<resource name="resource3">
<codes>
<code id="2" field1="value81" field2="value82" override="true" />
</codes>
</resource>
</resources>
output.xml
<resources>
<resource name="resource1">
<codes>
<code id="1" field1="value71" field2="value72" override="true" />
<code id="2" field1="value21" field2="value22" override="false" />
<code id="3" field1="value31" field2="value32" override="true" />
<code id="4" field1="value91" field2="value92" override="true" />
</codes>
</resource>
<resource name="resource2">
<codes>
<code id="1" field1="value11" field2="value12" override="true" />
</codes>
</resource>
<resource name="resource3">
<codes>
<code id="2" field1="value81" field2="value82" override="true" />
</codes>
</resource>
</resources>
答案 0 :(得分:1)
当您似乎使用Java运行XSLT时,可以考虑使用Saxon 9(在Maven上的开源HE版本中可用于Java(当前最新版本的Saxon 9.9 HE位于Saxon的https://search.maven.org/artifact/net.sf.saxon/Saxon-HE/9.9.0-2/jar) 9.8 HE在https://search.maven.org/artifact/net.sf.saxon/Saxon-HE/9.8.0-14/jar和Sourceforge https://sourceforge.net/projects/saxon/files/Saxon-HE/)使用XSLT 3或2代替内置的Oracle / Apache Xalan处理器支持的20年历史的XSLT 1。
使用XSLT 3,您可以将其视为嵌套分组问题,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<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="doc2">
<resources>
<resource name="resource1">
<codes>
<code id="1" field1="value71" field2="value72" override="true" />
<code id="2" field1="value81" field2="value82" override="true" />
<code id="4" field1="value91" field2="value92" override="true" />
</codes>
</resource>
<resource name="resource3">
<codes>
<code id="2" field1="value81" field2="value82" override="true" />
</codes>
</resource>
</resources>
</xsl:param>
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="resources">
<xsl:copy>
<xsl:for-each-group select="resource, $doc2/resources/resource" group-by="@name">
<resource>
<xsl:apply-templates select="@*"/>
<codes>
<xsl:for-each-group select="current-group()!codes/code" group-by="@id">
<xsl:apply-templates
select="if (current-group()[2] and ./@override = 'true')
then current-group()[2]
else ."/>
</xsl:for-each-group>
</codes>
</resource>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/jyH9rNn/3有一个在线示例,该示例出于紧凑性和完整性的目的而将第二个文档用作内联参数,但是您当然可以传入第二个文件的URI并使用例如改为<xsl:param name="doc2" select="doc("file2.xml")"/>
。
关于XSLT的介绍,可以在https://cranesoftwrights.github.io/books/ptux/index.htm上获得一本免费的书,《使用XSLT和XPath进行实用转换》。