0

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

4

2 回答 2

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

在将模板应用于元素的子元素时,您还需要排除该元素,否则您将获得输出元素的第二个副本以及其中的副本。最简单的方法是将模板替换为以下模板subtitlexmlSubtitleTitleDetailmatch="/"match="/*"

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

如果您对其他模板中的其他元素有类似的特殊处理,您可以将它们添加到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" />
于 2013-07-04T13:14:17.440 回答
0

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

<xsl:if test="following-sibling::subtitle"> 
  <Subtitle>123</Subtitle>
</xsl:if>
于 2013-07-04T13:14:09.070 回答