XSLT - 如何指定有序或从属操作

时间:2015-11-03 16:02:19

标签: xml xslt xpath

我有一个xslt模板,可以简化源代码,如下所示: 1)如果为空,则删除元素 p 2)如果元素 p 是当前级别的元素 p 的唯一实例,则“展开”元素 p 的内容。

我面临的挑战是,在行动#1完成之前,行动#2的条件并不明显。我的问题是,有没有办法指定“在行动#1完成后执行行动#2”?

为了给出具体信息,我的模板将检测以下内容

<li><p>Some words</p></li>

并将其简化为:

<li>Some words</li>

但如果我碰到这个:

<li><p>Some words</p><p/></li>

行动#1将被应用,但行动#2不会,导致:

<li><p>Some words</p></li>

而非预期:

<li>Some words</li>

我的模板如下:

<xsl:template match="p">
    <xsl:choose>
        <xsl:when test="normalize-space(.) = '' and not(@conref) and .[not(*)]">
            <xsl:message>Delete empty p.</xsl:message>
        </xsl:when>
        <xsl:when test="parent::li[count(p)=1 and not(./p[@id]) and not(./p[@conref])]">
            <xsl:message>Unwrap superfluous p.</xsl:message>
            <xsl:apply-templates/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy>
                <xsl:message>Print p as is.</xsl:message>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

1 个答案:

答案 0 :(得分:1)

  

1)如果空,则删除元素
  2)&#34;展开&#34;元素p的内容,如果它是当前级别的元素p的唯一实例   ...
  我的问题是,有没有办法在行动后指定&#34;做行动#2    #1完成&#34;?

我相信这些规则可以合并为一个:

XSLT 1.0

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

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

<xsl:template match="p[not(@* or node()) or not((preceding-sibling::p|following-sibling::p)[@* or node()])]">
    <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

测试输入:

<root>
    <li>
        <p></p>
    </li>
    <li>
        <p>a</p>
    </li>
    <li>
        <p>b</p>
        <p>c</p>
    </li>
    <li>
        <p>d</p>
        <p></p>
    </li>
</root>

<强>结果

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <li/>
   <li>a</li>
   <li>
      <p>b</p>
      <p>c</p>
   </li>
   <li>d</li>
</root>

请注意,从空元素的上下文中应用模板是良性的。