XSL1.0:如何在特定条件下仅解析标记的文本内容

时间:2014-01-14 19:06:55

标签: xml xslt xpath xslt-1.0

我有一个我无法解决的简单问题。 我有以下xml和xsl。当我们不在“标题”标签内时,我需要打印出包含其内容的SPAN和P标签。在这种情况下,我只想打印出他们的内容。 这是我的代码的摘录。现在我总是打印标签和内容,无法实现我想要的。 这就是我正在打印的内容:

<?xml version="1.0" encoding="utf-8"?>
<article class="story-ipad sortir">
    <title>
    <p>Il était une fois
        <span>à jamais</span>
    </p>
    <title>
    <text>
        <p>Resequam, necullitae exerio quis por si dolecature et mincta pro. <br/>
        </p>
        <span>La Belle et la Bête,</span>
    </text>
</article>

这就是我想要的:

<?xml version="1.0" encoding="utf-8"?>
<article class="story-ipad sortir">
    <title>
    Il était une fois à jamais
    </title>
    <text>
        <p>Resequam, necullitae exerio quis por si dolecature et mincta pro. <br/>
        </p>
        <span>La Belle et la Bête,</span>
    </tex

T&GT;

我无法修改代码太多,我想要做的是在我的最后一个匹配许多html标签的模板中添加一个异常,如果标签正在分析则有不同的标题// title / span ecc ....否则为我只是从“倾斜”中调用另一个模板,但仅限于span和p标签,因为所有其他标签必须表现不同。你能帮助我吗?

<xsl:template match="span|div|font|
        tt|i|b|big|small|u|s|strike|
        em|strong|q|sub|sup|cite|abbr|acronym|
        hr|blockquote|center|
        img|
        table|col|colgroup|thead|tfoot|tbody|tr|p|
        th|td|summary" name="html-noclass-t">

如果标签在某个特定路径下,则可以找到一个条件                                                                    


<?xml version="1.0" encoding="utf-8"?>
<doc xml:lang="fr">
    <article>
        <titles id="U1402860665587eXC">
            <title id="U1402864848468jy">
                <p id="U1402864848468C8D">Il était une fois <br/>
                    <span id="U1402864848468aP">à jamais</span>
                </p>
                </br>
            </title>
        </titles>
        <texte id="U14028606655875nG">
            <p>Resequam, necullitae exerio quis por si dolecature et mincta pro. <br/>
            </p>
            <span id="U1402864848468liD">La Belle et la Bête,</span>
        </texte>
    </article>
</doc>

使用XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8" indent="no"/>


    <xsl:template match="/">
        <xsl:apply-templates select="/doc/article" />
    </xsl:template>

    <xsl:template match="/doc/article">
        <article class="story-ipad sortir">
            <xsl:call-template name="header"/>
            <xsl:call-template name="text"/>
        </article>
    </xsl:template>

    <xsl:template name="header">
        <xsl:choose>
            <xsl:when test="//article/titles/title">
                <xsl:apply-templates select="//article/titles/title"/>
            </xsl:when>
            <xsl:otherwise/>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="text">
        <xsl:choose>
            <xsl:when test="//text">
                <xsl:apply-templates select="//text"/>
            </xsl:when>
            <xsl:otherwise/>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="span|div|font|
    tt|i|b|big|small|u|s|strike|
    em|strong|q|sub|sup|cite|abbr|acronym|
    hr|blockquote|center|
    img|
    table|col|colgroup|thead|tfoot|tbody|tr|p|
    th|td|summary" name="html-noclass-t">
        <xsl:element name="{name()}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

2 个答案:

答案 0 :(得分:2)

听起来你正在寻找的是XSLT modes

答案 1 :(得分:2)

我想知道你是否过于复杂化了。如果您希望<title>元素包含纯文本内容,则可以直接编写title元素并复制文本内容,而无需调用或应用模板。如果您想要<title>元素的某些后代的特殊行为,那么您可以编写具有不同匹配项的不同模板,例如:像这样:

我建议尝试这样的事情做你想做的事情:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="utf-8" indent="yes"/>

  <xsl:template match="/">
    <xsl:apply-templates select="/doc/article" />
  </xsl:template>

  <xsl:template match="/doc/article">
    <article class="story-ipad sortir">
      <title>
        <xsl:apply-templates select="titles/title"/>
      </title>
      <text>
        <xsl:apply-templates select="texte/*"/>
      </text>
    </article>
  </xsl:template>

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

  <xsl:template match="title//*[self::p or self::span or self::br]">
    <xsl:apply-templates select="node()"/>
  </xsl:template>

</xsl:stylesheet>

当应用于您的源文档时(我修改了它,因为它有一个没有匹配的开头的关闭</br>):

<?xml version="1.0" encoding="utf-8"?>
<article class="story-ipad sortir">
  <title>Il était une fois à jamais</title>
  <text>
    <p>Resequam, necullitae exerio quis por si dolecature et mincta pro. <br/>
    </p>
    <span>La Belle et la Bête,</span>
  </text>
</article>

出来了:

<?xml version="1.0" encoding="utf-8"?>
<article class="story-ipad sortir">
  <title>
    <title>
      Il était une fois 
      à jamais


    </title>
  </title>
  <text>
    <p>Resequam, necullitae exerio quis por si dolecature et mincta pro. <br/>
    </p>
    <span>La Belle et la Bête,</span>
  </text>
</article>

我注意到了另一件事:你正在使用像

这样的结构
<xsl:choose>
    <xsl:when test="//article/titles/title">
        <xsl:apply-templates select="//article/titles/title"/>
    </xsl:when>
    <xsl:otherwise/>
</xsl:choose>

这相当于这一行:

<xsl:apply-templates select="//article/titles/title"/>

在任何情况下都可以省略空<xsl:otherwise>,这会留下一个案例。在测试单个案例时,<xsl:if>更好。但总的来说,<xsl:if><xsl:choose>被过度使用,因为在很多情况下,<xsl:apply-templates>会完成这项工作,并且在XSLT中被认为是更好的做法。

你做的是多余的双重检查:你首先检查“有什么东西要供给<xsl:apply-templates>吗?”,如果没有供应,你什么都不做。但是,如果没有提供任何内容,<xsl:apply-templates>无论如何都不会做任何事情。所以,不需要检查。如果没有标题,<xsl:apply-templates>将不会执行任何操作,如果有标题,则无论如何都会调用它。