Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用xslt合并xml文件并删除空元素_Xml_Xslt_Xpath_Merge - Fatal编程技术网

如何使用xslt合并xml文件并删除空元素

如何使用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:


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())]" />