如何使用xslt合并xml文件并删除空元素
我有几个文件要合并,忽略空元素 例如: 文件1:如何使用xslt合并xml文件并删除空元素,xml,xslt,xpath,merge,Xml,Xslt,Xpath,Merge,我有几个文件要合并,忽略空元素 例如: 文件1: 1. 2. 3. 4. 文件2: <ds> <ac> <g1>9</f1> <g2>10</f2> </ac> <ac> <g1>11</f1> <g2>12</f2> </ac> </ds>
1.
2.
3.
4.
文件2:
<ds>
<ac>
<g1>9</f1>
<g2>10</f2>
</ac>
<ac>
<g1>11</f1>
<g2>12</f2>
</ac>
</ds>
9
10
11
12
和文件3:
<ds>
<rs>
<k1>A</f1>
<k2>B</f2>
<k3></k3>
</rs>
<rs>
<k1>C</f1>
<k2>B</f2>
<k3/>
</rs>
</ds>
A.
B
C
B
我想指出:
<ds>
<sk>
<f1>1</f1>
<f2>2</f2>
</sk>
<sk>
<f1>3</f1>
<f2>4</f2>
</sk>
<ac>
<g1>9</f1>
<g2>10</f2>
</ac>
<ac>
<g1>11</f1>
<g2>12</f2>
</ac>
<rs>
<k1>A</f1>
<k2>B</f2>
</rs>
<rs>
<k1>C</f1>
<k2>B</f2>
</rs>
</ds>
1.
2.
3.
4.
9
10
11
12
A.
B
C
B
我曾尝试将其作为xslt:
<?xml version="1.0" ?>
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xml:space="preserve"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/ds">
<xsl:copy-of select="document('File1')/ds/sk"/>
<xsl:copy-of select="document('File2')/ds/ac"/>
<xsl:copy-of select="document('File3')/ds/rs"/>
</xsl:template>
</xsl:transform>
输入为File1。文件是合并的,但我不知道如何删除File3中的或之类的空元素。
有什么想法吗?假设您的所有XML文件实际上都是格式良好的,您应该从使用XSLT标识转换开始
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
注意,如果File1
上的document
函数恰好是XSLT本身的输入文件,则可能不需要使用该函数
然后,要删除空元素,只需添加如下模板:
<xsl:template match="*[not(*)][not(normalize-space())]" />
试试这个XSLT
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<xsl:apply-templates select="document('File1')/ds/sk" />
<xsl:apply-templates select="document('File2')/ds/ac" />
<xsl:apply-templates select="document('File3')/ds/rs" />
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(*)][not(normalize-space())]" />
</xsl:transform>
我不明白为什么,但使用这个xslt解决了这个问题
注意:您使用Altova(使用msxml作为解析器)的表现很好。在我的代码(powerbuilder)中,我需要使用这个…欢迎使用SO。不幸的是,我真的看不到您在做什么:您的xslt不完整,
xsl:for-each
没有正文,也没有关闭。我假设您的代码正在执行您所说的“合并”所指的任何操作?这是一个错误,不是针对每个副本,而是针对每个副本。谢谢,但您仍然应该关闭它们以获得合法的XML。(复制和粘贴测试代码通常是个好主意。)Thks,我已经尝试了给定的xslt,但根本没有输出xml。注意:在我最初的帖子中有一个错误,我使用的是副本而不是每个。。。我正在使用msxml进行转换。请随意修改您的初始帖子以纠正错误。另外,我对我的答案做了一个小的修改。您确实需要确保document
函数为每个文件引用了正确的文件路径。如果只输入File1.xml
,它(可能)会在XSLT所在的文件夹中查找xml。谢谢File1.xml位于同一目录中,但我仍然使用absolut路径。我使用的是c:\test\File1.xml,尝试了file:///c:/test/File1.xml,结果是一样的,没有输出文件…如果替换xsl:apply templates
而不是xsl:copy of
,我的答案会产生输出吗?Tim的答案有什么不同?
<xsl:template match="*[not(*)][not(normalize-space())]" />
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<xsl:apply-templates select="document('File1')/ds/sk" />
<xsl:apply-templates select="document('File2')/ds/ac" />
<xsl:apply-templates select="document('File3')/ds/rs" />
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(*)][not(normalize-space())]" />
</xsl:transform>
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="document('File1')/ds/sk" />
<xsl:apply-templates select="document('File2')/ds/ac" />
<xsl:apply-templates select="document('File3')/ds/rs" />
</xls:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(*)][not(normalize-space())]" />