我有各种已合并的xml文件。这意味着存在重复的根元素和重复的xml声明。
我想在顶部运行转换以删除重复项并使用新的根元素包装内容。
这可以使用xslt吗?
答案 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来修复错误的合并结果。