使用xslt删除xml文件中的重复xml声明

时间:2018-02-21 20:37:48

标签: xml xslt

我有各种已合并的xml文件。这意味着存在重复的根元素和重复的xml声明。

我想在顶部运行转换以删除重复项并使用新的根元素包装内容。

这可以使用xslt吗?

1 个答案:

答案 0 :(得分:2)

这取决于您如何使用XSLT,以及如何提供输入源。通常,您拥有的格式不是XML文档,并且使用各种XML声明,它甚至不是外部实体或片段。因此,即使使用XPath 3和parse-xml-fragment,您首先需要删除XML声明。

然而,您可以尝试使用unparsed-text加载文档,然后使用带有正则表达式的replace删除XML声明,最后parse-xml-fragment将片段解析为节点然后进一步转换,例如删除各种根元素并将其子节点包装成一个公共节点:

<?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"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:param name="fragment-uri" as="xs:string" select="'fragment-input1.txt'"/>

    <xsl:param name="fragments" as="xs:string" select="unparsed-text($fragment-uri)"/>

    <xsl:param name="declaration-regex" as="xs:string"><![CDATA[<\?xml\s+[^>]*?\?>]]></xsl:param>

    <xsl:variable name="fragments-with-declarations-stripped" as="xs:string"
        select="replace($fragments, $declaration-regex, '')"/>

    <xsl:template match="/" name="xsl:initial-template">
        <root>
            <xsl:copy-of select="parse-xml-fragment($fragments-with-declarations-stripped)/*/node()"/>
        </root> 
    </xsl:template>

</xsl:stylesheet>

表单

的输入“fragment-input1.txt”
    <?xml version='1.0'?>
    <root1>
      <foo1>...</foo1>
    </root1>
    <?xml version="1.0"?><root2><foo2>...</foo2></root2>
    <?xml version="1.0" encoding="UTF-8"?>
    <?xml-stylesheet type="text/xsl" href="foo.xsl"?>
    <root3>
      <foo3>...</foo3>
    </root3>
    <?xml version="1.0" encoding='ISO-8859-1' standalone="yes"?>
    <root4>
      <foo4>...</foo4>
    </root4>

就是这样转化为结果:

<?xml version="1.0" encoding="UTF-8"?><root>
                  <foo1>...</foo1>
                <foo2>...</foo2>
                  <foo3>...</foo3>

                  <foo4>...</foo4>
                </root>

注意:我不确定使用的正则表达式是否足以删除任何允许形式的XML声明。

只需使用XSLT和document和/或doc和/或collection和/或xsl:merge来合并,就可以避免整个容易出错的过程正确使用不同的文件而不是使用XSLT来修复错误的合并结果。