XSLT防止或删除多个引用

时间:2013-05-26 13:16:52

标签: xml xslt

我有以下输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
    <person id="1" type="parent">
        <name>father</name>
        <person-reference type="child">3</person-reference>
        <person-reference type="child">4</person-reference>
    </person>
    <person id="2" type="parent">
        <name>mother</name>
        <person-reference type="child">3</person-reference>
        <person-reference type="child">4</person-reference>
    </person>
    <person id="3">
        <name>brother</name>
    </person>
    <person id="4">
        <name>sister</name>
    </person>
</persons>

通过以下XSLT转换:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/persons">
        <relations>
            <xsl:apply-templates select="person[@type = 'parent']"/>
        </relations>
    </xsl:template>

    <xsl:template match="person">
        <parent>
            <name><xsl:value-of select="name"/></name>
        </parent>

        <xsl:apply-templates select="person-reference[@type = 'child']"/>
    </xsl:template>

    <xsl:template match="person-reference">
        <child>
            <name><xsl:value-of select="//person[@id = current()]/name"/></name>
        </child>
    </xsl:template>
</xsl:stylesheet>

我得到这个XML(结果):

<?xml version="1.0" encoding="UTF-8"?>
<relations xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <parent>
        <name>father</name>
    </parent>
    <child>
        <name>brother</name>
    </child>
    <child>
        <name>sister</name>
    </child>
    <parent>
        <name>mother</name>
    </parent>
    <child>
        <name>brother</name>
    </child>
    <child>
        <name>sister</name>
    </child>
</relations>

但我想要的是这个XML(预期结果):

<?xml version="1.0" encoding="UTF-8"?>
<relations xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <parent>
        <name>father</name>
    </parent>
    <child>
        <name>brother</name>
    </child>
    <child>
        <name>sister</name>
    </child>
    <parent>
        <name>mother</name>
    </parent>
</relations>

或者这个(可选的预期结果):

<?xml version="1.0" encoding="UTF-8"?>
<relations xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <parent>
        <name>father</name>
    </parent>
    <parent>
        <name>mother</name>
    </parent>
    <child>
        <name>brother</name>
    </child>
    <child>
        <name>sister</name>
    </child>
</relations>

是否有办法使用XSLT来防止使用像我这样的引用进行双输出?

1 个答案:

答案 0 :(得分:1)

为防止重复的人参考(使用xslt-1.0),您可以使用xsl-key

<xsl:key name="kReference" match="person-reference"  use="."/>

并测试当前参考是否是第一个参考。

<xsl:if test=" generate-id()= generate-id( key( 'kReference', current()/text())[1] )" >

因此尝试这个:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:key name="kReference" match="person-reference"  use="."/>

    <xsl:template match="/persons">
        <relations>
            <xsl:apply-templates select="person[@type = 'parent']"/>
        </relations>
    </xsl:template>

    <xsl:template match="person">
        <parent>
            <name>
                <xsl:value-of select="name"/>
            </name>
        </parent>

        <xsl:apply-templates select="person-reference"/>
    </xsl:template>

    <xsl:template match="person-reference">
        <xsl:if test=" generate-id()= generate-id( key( 'kReference', current()/text())[1] )" >
            <child>
                <name>
                    <xsl:value-of select="//person[@id = current()]/name"/>
                </name>
            </child>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

但我仍然担心这个问题背后还有更多。