在xslt v2.0中检查上层标记中的条件

时间:2017-05-25 05:57:43

标签: xslt xslt-2.0

我有这个要求,如果<Group>下的<Section>标记不存在,我只需填充<Group>下的<Data>标记。我无法获得我想要的正确输出。例如:

INPUT

<Record>
<Data>
    <ID>1234DFD57</ID>
    <Group>
        <abc-KD>243fds</abc-KD>
    </Group>
    <Section>
        <ID>33-2311</ID>
        <Group>
            <abc-KD>NORM</abc-KD>
        </Group>
        <Date>2017-03-25</Date>
    </Section>
    <Date>2017-03-25</Date>
</Data>
</Record>

预期输出

<Record>
<Data>
    <ID>1234DFD57</ID>
    <Group>
        <abc-KD>243fds</abc-KD>
    </Group>
    <Section>
        <ID>33-2311</ID>
        <Date>2017-03-25</Date>
    </Section>
    <Date>2017-03-25</Date>
</Data>
</Record>

XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="Section">
    <xsl:copy>
        <xsl:copy-of select="ID"/>
        <xsl:if test="normalize-space(string(../Group)) = ''">
            <xsl:copy-of select="Group"/>
        </xsl:if>
        <xsl:copy-of select="Date"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

非常感谢您的反馈。

此致

1 个答案:

答案 0 :(得分:0)

您当前的样式表可以完成这项工作。更有效的方式是:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <!-- identity transform template -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <!-- do nothing for the Group -->
    <xsl:template match="Section[normalize-space(parent::Data/Group) != '']/Group"/>
</xsl:stylesheet>

身份转换模板是复制xml中每个节点的模板,同时按文档顺序递归处理它们。 第二个模板将Group元素与所需条件匹配,并且不对其执行任何操作,因此在输出中省略它们。

@match中的x路径可以解决问题:
Section[normalize-space(parent::Data/Group) != '']/Group

它匹配Section/Group DataGroup不存在或具有空值(空格字符除外)的typedef struct { int a; } type; 元素。