2013-07-04 73 views
0

我正在将一个XML文件转换为另一种XML格式。检查节点是否存在于具有XSLT的文档中

下面是示例源文件:

<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。如何检查源文件是否有字幕信息?

回答

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元素的孩子时,否则你将TitleDetail以及它里面的一个后得到Subtitle输出元素的第二个副本。最简单的方法是用下面的match="/*"一个替代

<xsl:template match="/*"> 
    <Product> 
     <xsl:apply-templates select="*[not(self::subtitle)]/> 
    </Product> 
</xsl:template> 

,以取代match="/"模板如果您有其他模板其他元素,你可以添加这些到not(),即select="*[not(self::subtitle | self::somethingelse)]"类似的特殊处理。

另外,您可以利用模板模式

<?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="."/></TitleText> 
      <xsl:apply-templates select="../subtitle" mode="in-title" /> 
     </TitleElement> 
    </TitleDetail> 
</xsl:template> 

<!-- in "in-title" mode, add a Subtitle element --> 
<xsl:template match="subtitle" mode="in-title"> 
    <Subtitle><xsl:value-of select="."/></Subtitle> 
</xsl:template> 

<!-- in normal mode, do nothing --> 
<xsl:template match="subtitle" /> 
+0

感谢您的帮助。我尝试了你的解决方案,但字幕标签已被替换两次:一个'Subtitle'是'TitleDetail'的后代,另一个是'Product'元素的后代。 “TitleDetail”中只需要一个'Subtitle'标签。附: - 我使用这一行。 – Tamara

+0

@Tamara我已经添加了一些可能的方法来解决这个问题。 –

+0

谢谢,它的工作原理。 – Tamara

0

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

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

感谢您的帮助。我忘了提及这个字幕不一定是在兄弟姐妹之后 - 这只是兄弟姐妹。 – Tamara

相关问题