我有一个XML文档,其结构类似于以下示例:
<p:Document versione="1.0"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DocumentHeader>
global header
</DocumentHeader>
<DocumentBody>
body 1
</DocumentBody>
<DocumentBody>
body 2
</DocumentBody>
</p:Document>
请注意,“全局标题”和“正文X”可能会出现嵌套的xml块,而不仅仅是纯文本。
我需要将此XML文件拆分为 - 在此示例中 - 两个XML文件,如下所示:
<p:Document versione="1.0"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DocumentHeader>
global header
</DocumentHeader>
<DocumentBody>
body 1
</DocumentBody>
</p:Document>
和
<p:Document versione="1.0"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DocumentHeader>
global header
</DocumentHeader>
<DocumentBody>
body 2
</DocumentBody>
</p:Document>
通常,我必须创建几个新的XML,每个DocumentBody节点一个,在每个创建的新文件中放置相同的DocumentHeader节点。
我认为XSL转换是最好的方法,但我不知道如何。 我尝试使用报告的示例here,但这些情况不管理“标头”节点。
<xsl:template match="/root">
<xsl:for-each select="DocumentBody">
<xsl:result-document method="xml" href="file_{@id}-output.xml">
<root>
<xsl:copy-of select="/root/@*" />
<DocumentBody>
<xsl:copy-of select="../@* | ." />
</DocumentBody>
</root>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
你能帮助我吗?
收到第一个回答后更新。 我使用建议的代码
通过Saxon工具执行转换<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:p="http://example.com/p">
<xsl:template match="/p:Document">
<xsl:for-each select="DocumentBody">
<xsl:result-document method="xml" href="file_{position()}-output.xml">
<p:Document>
<xsl:copy-of select="/*/@*, ../DocumentHeader, ." />
</p:Document>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我注意到原始xml和其中一个新文档之间存在以下差异。 原文(部分内容):
<p:Document versione="1.0"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DocumentHeader>
文件1(部分):
<p:Document
xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.0" versione="1.0">
<DocumentHeader
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
也许我在这个选择中需要差异表达式?
<xsl:copy-of select="/*/@*, ../DocumentHeader, ." />
谢谢!
答案 0 :(得分:0)
将您的示例XML更正为名称空间良好的形式:
<p:Document versione="1.0" xmlns:p="http://example.com/p">
<DocumentHeader>
global header
</DocumentHeader>
<DocumentBody>
body 1
</DocumentBody>
<DocumentBody>
body 2
</DocumentBody>
</p:Document>
以下XSLT 2.0样式表应该满足您的要求:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:p="http://example.com/p">
<xsl:template match="/p:Document">
<xsl:for-each select="DocumentBody">
<xsl:result-document method="xml" href="file_{position()}-output.xml">
<p:Document>
<xsl:copy-of select="/*/@*, ../DocumentHeader, ." />
</p:Document>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
copy-of
将三件事复制到结果文档中 - 原始根元素的属性,DocumentHeader
和当前DocumentBody
。如上所述,假设DocumentHeader和DocumentBody元素不在命名空间中,如果它们是,那么您需要在样式表中使用合适的前缀声明它并相应地调整XPath表达式。
在此上下文中,position()
函数为您提供了一个基本上是&#34;迭代计数器的数字&#34;对于for-each
- 1表示第一个DocumentBody
,2表示第二个,等等。
答案 1 :(得分:0)
以下转变 - 强烈基于@ IanRoberts的 - 应该最终解决问题:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.0">
<xsl:template match="/p:Document">
<xsl:for-each select="DocumentBody">
<xsl:result-document method="xml"
href="{substring-before(base-uri(),'.xml')}_doc_n°_{position()}.xml">
<p:Document versione="1.0"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:copy-of select="/*/@*, ../DocumentHeader, ." />
</p:Document>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
假设原始xml名为example.xml,新文件的名称为“example_doc_n°1.xml”等。 注意:对于对意大利电子发票感兴趣的人,名为“Fattura Elettronica”,请将文件替换为FatturaElettronica。