XSLT:在输出XML中的特定位置添加节点(如果缺少)

时间:2014-09-11 09:13:22

标签: xml xslt

我正在尝试建立一个转型:

  • 如果发现该节点不存在于父
  • 的实例中,则添加“默认”节点
  • 在输出XML
  • 中的特定位置添加该默认节点

例如,如果没有为某人提供“年龄”,那么它应该在所需“名称”节点之后的节点中默认为“未知”:

<People>
    <Person>
        <Name>Bob Smith</Name>
        <Age>34</Age>
        <Gender>Male></Gender>
    </Person>
    <Person>
        <Name>Jane Smith</Name>
        <Gender>Female</Gender>
    </Person>
</People>

变为:

<People>
    <Person>
        <Name>Bob Smith</Name>
        <Age>34</Age>
        <Gender>Male></Gender>
    </Person>
    <Person>
        <Name>Jane Smith</Name>
        <Age>Unknown</Age>
        <Gender>Female</Gender>
    </Person>
</People>

我有以下XSLT,它正确添加了默认值,但它将默认值添加到Person部分的 end 。我需要在Name节点之后添加节点:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:p="http://services.ic.gov.uk/common-person/v1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Person[not(Age)]">
        <Person>
            <xsl:apply-templates select="node()|@*" />
            <Age>Unknown</Age>
        </Person>
    </xsl:template>
</xsl:stylesheet>

有没有人可以帮我实现在“名称”节点之后添加“年龄”节点的额外要求?

非常感谢!

1 个答案:

答案 0 :(得分:3)

如果您知道总会有Name,那么最简单的方法就是将逻辑移到Name模板中:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:p="http://services.ic.gov.uk/common-person/v1.0">

    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:strip-space elements="*" />

    <xsl:template match="node()|@*" name="ident">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Name[not(../Age)]">
        <!-- copy the Name as usual -->
        <xsl:call-template name="ident" />
        <!-- and add Age immediately after it -->
        <Age>Unknown</Age>
    </xsl:template>
</xsl:stylesheet>

如果Person可以有多个Name,您可能需要使匹配更具体,例如Name[last()][not(../Age)] AgeName内{em} }之后的Person之后添加{{1}},而不是在每个之后添加{{1}}。