使用XSLT检查文档中是否存在节点

时间:2013-07-04 13:06:54

标签: xslt

我正在将一个XML文件转换为另一种XML格式。

以下是示例源文件:

<xml>
     <title>Pride and Prejudice</title>
     <subtitle>Love Novel</subtitle>
</xml>

这是xsl文件:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <Product>
        <xsl:apply-templates/>
    </Product>
</xsl:template>

<xsl:template match="title">
    <TitleDetail>
        <TitleType>01</TitleType>
        <TitleElement>
            <TitleElementLevel>01</TitleElementLevel>
            <TitleText><xsl:value-of select="current()"/></TitleText>
             <!--Here Problem!!!-->
            <xsl:if test="subtitle"> 
                <Subtitle>123</Subtitle>
            </xsl:if>
        </TitleElement>
    </TitleDetail>
</xsl:template>

想法是,如果源文件包含字幕标记,我需要将“字幕”节点插入“TitleDetail”,但“if”条件返回false。如何检查源文件是否有字幕信息?

2 个答案:

答案 0 :(得分:1)

我会定义另一个模板

<xsl:template match="subtitle">
  <Subtitle><xsl:value-of select="."/></Subtitle>
</xsl:template>

然后在主title模板中将模板应用到../subtitle(即从title元素导航到相应的subtitle

<TitleText><xsl:value-of select="."/></TitleText>
<xsl:apply-templates select="../subtitle" />

您不需要进行if测试,因为如果apply-templates找不到任何匹配的节点,select将无法执行任何操作。

在将模板应用于subtitle元素的子元素时,您还需要排除 xml元素,否则您将获得{{1}的第二个副本Subtitle之后的输出元素以及它内部的输出元素。最简单的方法是将TitleDetail模板替换为以下match="/"一个

match="/*"

如果您对其他模板中的其他元素有类似的特殊处理,则可以将其添加到<xsl:template match="/*"> <Product> <xsl:apply-templates select="*[not(self::subtitle)]/> </Product> </xsl:template> ,即not()

或者,您可以使用模板模式

select="*[not(self::subtitle | self::somethingelse)]"

答案 1 :(得分:0)

如果我正确理解了这个问题,你可以试试这个:

<xsl:if test="following-sibling::subtitle"> 
  <Subtitle>123</Subtitle>
</xsl:if>