提取后一些数据丢失

时间:2017-03-23 11:42:50

标签: xml xslt xslt-2.0

我有一个xml文件来spilit,当我根据信息编写spsiting文件的xslt时,但是在扫描文件后,一些不是文件祖先的元素在转换中丢失

先谢谢

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<parent id="1">
    <misc1>**Some DATA**</misc1>
    <misc2>**Some DATA**</misc2>
    <child1 id="2">
        <child1-misc1>**Some DATA**</child1-misc1>
        <file name="A.xml"><a id="11">aaa</a></file>
        <file name="B.xml"><b id="21">bbb</b></file>
    </child1>
    <child2 id="3">
        <child2-misc1>**Some DATA**</child2-misc1>
        <child2-misc2>**Some DATA**</child2-misc2>
        <file name="C.xml"><c id="31">ccc</c></file>
        <file name="D.xml"><d id="41">ddd</d></file>
    </child2>
</parent>

我的XSL

<?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"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:template match="file">
        <xsl:variable name="name" select="@name"/>
        <xsl:result-document method="xml" href="{$name}" indent="yes">
            <xsl:call-template name="spilit">
                <xsl:with-param name="name" select="$name"/>
                <xsl:with-param name="element" select="root()"/>
            </xsl:call-template>
        </xsl:result-document>
    </xsl:template>

    <xsl:template name="spilit">
        <xsl:param name="name"/>
        <xsl:param name="element"/>
        <xsl:for-each select="$element[descendant-or-self::file[@name eq $name]]">
            <xsl:copy>
                <xsl:choose>
                    <xsl:when test="self::file">
                        <xsl:copy-of select="node()"></xsl:copy-of>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:copy-of select="@*"></xsl:copy-of>
                        <xsl:call-template name="spilit">
                            <xsl:with-param name="name" select="$name"/>
                            <xsl:with-param name="element" select="child::*[descendant-or-self::file[@name eq $name]]"/>
                        </xsl:call-template>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:copy>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

当前输出

A.XML

<?xml version="1.0" encoding="UTF-8"?>
<parent id="1">
   <child1 id="2">
      <file><a id="11">aaa</a></file>
   </child1>
</parent>

B.XML

<?xml version="1.0" encoding="UTF-8"?>
<parent id="1">
   <child1 id="2">
      <file><b id="21">bbb</b></file>
   </child1>
</parent>

C.xml

<?xml version="1.0" encoding="UTF-8"?>
<parent id="1">
   <child2 id="3">
      <file><c id="31">ccc</c></file>
   </child2>
</parent>

D.xml

<?xml version="1.0" encoding="UTF-8"?>
<parent id="1">
   <child2 id="3">
      <file><d id="41">ddd</d></file>
   </child2>
</parent>

预期输出

A.XML

<?xml version="1.0" encoding="UTF-8"?>
<parent id="1">
    <misc1>**Some DATA**</misc1>
    <misc2>**Some DATA**</misc2>
    <child1 id="2">
        <child1-misc1>**Some DATA**</child1-misc1>
        <file><a id="11">aaa</a></file>
    </child1>
</parent>

B.XML

<?xml version="1.0" encoding="UTF-8"?>
<parent id="1">
    <misc1>**Some DATA**</misc1>
    <misc2>**Some DATA**</misc2>
    <child1 id="2">
        <child1-misc1>**Some DATA**</child1-misc1>
        <file><b id="21">bbb</b></file>
    </child1>
</parent>

C.xml

<?xml version="1.0" encoding="UTF-8"?>
<parent id="1">
    <misc1>**Some DATA**</misc1>
    <misc2>**Some DATA**</misc2>
    <child2 id="3">
        <child2-misc1>**Some DATA**</child2-misc1>
        <child2-misc2>**Some DATA**</child2-misc2>
        <file><c id="31">ccc</c></file>
    </child2>
</parent>

D.xml

<?xml version="1.0" encoding="UTF-8"?>
<parent id="1">
    <misc1>**Some DATA**</misc1>
    <misc2>**Some DATA**</misc2>
    <child2 id="3">
        <child2-misc1>**Some DATA**</child2-misc1>
        <child2-misc2>**Some DATA**</child2-misc2>
        <file><d id="41">ddd</d></file>
    </child2>
</parent>

1 个答案:

答案 0 :(得分:1)

我认为您只需要一个额外的行来复制当前节点中没有file后代的子节点。

<xsl:copy-of select="*[not(descendant-or-self::file)]" />

尝试将spilit模板更改为此...

<xsl:template name="spilit">
    <xsl:param name="name"/>
    <xsl:param name="element"/>
    <xsl:for-each select="$element[descendant-or-self::file[@name eq $name]]">
        <xsl:copy>
            <xsl:choose>
                <xsl:when test="self::file">
                    <xsl:copy-of select="node()"></xsl:copy-of>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="@*"></xsl:copy-of>
                    <xsl:copy-of select="*[not(descendant-or-self::file)]" />
                    <xsl:call-template name="spilit">
                        <xsl:with-param name="name" select="$name"/>
                        <xsl:with-param name="element" select="child::*[descendant-or-self::file[@name eq $name]]"/>
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:for-each>
</xsl:template>