使用XSLT在输出文件中仅将不同文件中的相同xml元素写入一次

时间:2015-01-20 17:25:27

标签: xml xslt

我有几个xml文件,它们都有一些共同的元素,有些元素是独有的。我需要使用xslt将这些元素的值仅输出一次到另一个xml文档。最好的方法是什么?

示例:

file a.xml

<someelement>Value</someelement>
<aelement>value</aelement>

file b.xml

<someelement>Value</someelement>
<belement>value</belement>

file c.xml

<someelement>Value</someelement>
<celement>value</celement>

的Output.xml

<someelement>Value</someelement>
<aelement>value</aelement>
<belement>value</belement>
<celement>value</celement>

我遍历一个文件,其中包含文件夹和子文件夹中xml文件的所有路径,并使用doc函数访问元素。

但是,目前,公共元素在输出文档中多次出现。

使用Saxon9he可以使用xslt 2.0吗?

感谢您的帮助和提示!

1 个答案:

答案 0 :(得分:0)

让我们假设您的&#34;索引&#34;文件是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<index>
    <file name="a.xml"/>
    <file name="b.xml"/>
    <file name="c.xml"/>
</index>

和&#34;内容&#34;文件,例如a.xml,就像这样(就像你在问题中写的那样,但是有一个包装元素):

<?xml version="1.0" encoding="UTF-8"?>
<awrapper>
    <someelement>Value</someelement>
    <aelement>a value</aelement>
    <aelement>a value bis</aelement>
</awrapper>

XSLT 2.0

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs">

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <mergeresult>
            <!-- start processing the first file -->
            <xsl:apply-templates select="index/file[1]">
                <xsl:with-param name="usedNames" select="()"/>
            </xsl:apply-templates>
        </mergeresult>
    </xsl:template>

    <xsl:template match="file">
        <xsl:param name="usedNames" as="xs:string*"/>
        <xsl:variable name="tree" select="document(@name)"/>
        <xsl:message select="(@name, $usedNames)"/>
        <!-- add only the xml elements with "new" names -->
        <xsl:sequence select="$tree/*/*[not((local-name()) = $usedNames)]"/>
        <!-- continue processing the next file -->
        <xsl:apply-templates select="following-sibling::file[1]">
            <xsl:with-param name="usedNames" select="
                distinct-values(($usedNames, for $el in $tree/*/* return local-name($el)))"/>
        </xsl:apply-templates>
    </xsl:template>

</xsl:stylesheet>

<强>输出

<?xml version="1.0" encoding="UTF-8"?>
<mergeresult>
   <someelement>Value</someelement>
   <aelement>a value</aelement>
   <aelement>a value bis</aelement>
   <belement>b value</belement>
   <celement>c value</celement>
</mergeresult>

建议的样式表:

  • 仅根据元素名称识别重复项(不确定这是否是您需要的)
  • 独立于&#34;内容&#34;的文档元素的名称。文件(在我的示例中为awrapper,每个内容文件可能不同)
  • 即使是&#34;内容&#34;也能正常运作file包含几个具有相同名称的元素(=它将它们全部放在输出中,在我的示例中,aelement都保留了)
  • 需要适应&#34; index&#34;的实际元素/属性名称。文件(在我的示例中为indexfile@name