[英]add top level tag once while merging xml files in xslt
我正在嘗試使用 xslt 和 saxon-HE 9.9.1 .NET 合並特定文件夾中的多個 xml 文件。 我需要創建一個通用合並,這樣我就不會在模板中添加靜態標簽以將其與不同節點的名稱一起使用,我嘗試在開始時創建一個循環以添加根或頂級標簽,但它也在 xml 結束之前關閉標記,但頂級標記存在問題 示例:XML File1:
<Arr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Src>
<name>C</name>
<pr>pr</pr>
<par>
<Q>
<isC>false</isC>
<name>hrh1</name>
<type>xx1</typ>
</Q>
</par>
<st />
</Src>
<Src>
<name>C</name>
<pr></pr>
<par>
<Q>
<isC>false</isC>
<name>hrh2</name>
<type>xx2</typ>
</Q>
</par>
<st>
<Src>
<name>st1</name>
<pr>prst1</pr>
<par>
<Q>
<isC>false</isC>
<name>q1</name>
<type>t1</type>
</Q>
<Q>
<isC>false</isC>
<name>q2</name>
<type>t2</type>
</Q>
</par>
<st />
</Src>
</st>
</Src>
</Arr>
XML文件2:
<Arr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Src>
<name>CFile2</name>
<pr>C2</pr>
<par>
<Q>
<isC>false</isC>
<name>hrh1</name>
<type>xx1</typ>
</Q>
</par>
<st />
</Src>
</Arr>
預期輸出:
<Arr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Src>
<name>C</name>
<pr>pr</pr>
<par>
<Q>
<isC>false</isC>
<name>hrh1</name>
<type>xx1</typ>
</Q>
</par>
<st />
</Src>
<Src>
<name>C</name>
<pr></pr>
<par>
<Q>
<isC>false</isC>
<name>hrh2</name>
<type>xx2</typ>
</Q>
</par>
<st>
<Src>
<name>st1</name>
<pr>prst1</pr>
<par>
<Q>
<isC>false</isC>
<name>q1</name>
<type>t1</type>
</Q>
<Q>
<isC>false</isC>
<name>q2</name>
<type>t2</type>
</Q>
</par>
<st />
</Src>
</st>
</Src>
<Src>
<name>CFile2</name>
<pr>C2</pr>
<par>
<Q>
<isC>false</isC>
<name>hrh1</name>
<type>xx1</typ>
</Q>
</par>
<st />
</Src>
</Arr>
由於頂級標簽關閉,我當前的模板會產生錯誤的輸出
<?xml version="1.0" encoding="windows-1256"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:user="http://tempuri.org/msxsl" >
<xsl:output method="xml" indent="yes" encoding="windows-1256" />
<xsl:template name="main">
<xsl:for-each select="collection('.?select=*.xml')/*">
<xsl:choose>
<xsl:when test="position() = 1">
<xsl:copy>
<xsl:copy-of select="/*/node()"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="/*/node()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我使用以下命令從 cmd 運行:
transform -it:main -xsl:merge_xml.xslt -o:output.xml
我當前的輸出是錯誤的
<Arr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Src>
<name>C</name>
<pr>pr</pr>
<par>
<Q>
<isC>false</isC>
<name>hrh1</name>
<type>xx1</typ>
</Q>
</par>
<st />
</Src>
<Src>
<name>C</name>
<pr></pr>
<par>
<Q>
<isC>false</isC>
<name>hrh2</name>
<type>xx2</typ>
</Q>
</par>
<st>
<Src>
<name>st1</name>
<pr>prst1</pr>
<par>
<Q>
<isC>false</isC>
<name>q1</name>
<type>t1</type>
</Q>
<Q>
<isC>false</isC>
<name>q2</name>
<type>t2</type>
</Q>
</par>
<st />
</Src>
</st>
</Src>
</Arr>
<Src>
<name>CFile2</name>
<pr>C2</pr>
<par>
<Q>
<isC>false</isC>
<name>hrh1</name>
<type>xx1</typ>
</Q>
</par>
<st />
</Src>
我會簡單地使用
<xsl:param name="uris" select="uri-collection('.?select=*.xml')"/>
<xsl:template name="xsl:initial-template">
<xsl:copy select="$uris => head() => doc()/*">
<xsl:copy-of select="($uris ! doc(.))/*/node()"/>
</xsl:copy>
</xsl:template>
如果 Saxon EE 是一個可以嘗試的選項,則能夠切換到流媒體
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all" expand-text="yes">
<xsl:function name="mf:merge" as="document-node()">
<xsl:param name="uris"/>
<xsl:source-document href="{head($uris)}" streamable="yes">
<xsl:document>
<xsl:copy select="*">
<xsl:copy-of select="node()"/>
<xsl:iterate select="tail($uris)">
<xsl:source-document href="{.}" streamable="yes">
<xsl:copy-of select="*/node()"/>
</xsl:source-document>
</xsl:iterate>
</xsl:copy>
</xsl:document>
</xsl:source-document>
</xsl:function>
<xsl:output method="xml" indent="yes"/>
<xsl:template name="xsl:initial-template">
<xsl:sequence select="mf:merge(uri-collection('?select=*.xml'))"/>
</xsl:template>
</xsl:stylesheet>
馬丁的解決方案會奏效,但我會這樣做:
<xsl:template name="xsl:initial-template">
<xsl:variable name="coll" select="collection('.?select=*.xml')"/>
<xsl:copy select="$coll[1]/*">
<xsl:copy-of select="$coll/*/*"/>
</xsl:copy>
</xsl:template>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.