无法使用XSLT匹配模式

时间:2014-12-24 08:16:33

标签: xslt xslt-2.0

我在XML下面。

<?xml version="1.0" encoding="UTF-8"?>
<list>
  <list.item>
    <label>(1)</label> This is first list item)
  </list.item>
  <list.item><label>
    <star.page>179</star.page> (2)</label>This is second)
  </list.item>
  <list.item><label>(3)</label>This is third)</list.item>
</list>

我的目标是。如果有star.page,我想打破块并重新创建它。我的意思是。 如果star.page位于list\list.item\label内,我想按照list.item\list打印star.page的顺序关闭它们,并重新创建列表list\list.item我正在使用以下内容XSLT。

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="/">
      <hmtl>
        <head>
          <title>New Version!</title>
        </head>
        <xsl:apply-templates/>
      </hmtl>
    </xsl:template>


    <xsl:template name="orderedlist" match="list">
      <ol class="eng-orderedlist orderedlist">
        <xsl:apply-templates/>
      </ol>
    </xsl:template>

    <xsl:template name="orderitem" match="list.item">
      <xsl:apply-templates select="./label/*[1][self::star.page]"/>
      <li class="item">
        <div class="para">
          <xsl:if test="./label">
            <span class="item-num">
              <xsl:value-of select="./label/text()"/>
            </span>
          </xsl:if>
          <xsl:choose>
            <xsl:when test="./node()">
              <xsl:apply-templates select="child::node()[not(self::label)]"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>&#160;</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </div>
      </li>
    </xsl:template>


    <xsl:template match="star.page">
      <xsl:choose>
        <xsl:when test="../../..[list] and ..[label]">
          <xsl:text disable-output-escaping="yes"><![CDATA[</ol>]]></xsl:text>
          <xsl:call-template name="runn_head"/>
          <xsl:text disable-output-escaping="yes"><![CDATA[<ol class="eng-orderedlist orderedlist">]]></xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:call-template name="runn_head"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>


    <xsl:template name="runn_head">
      <div class="x">
        <xsl:value-of select="."/>
      </div>
    </xsl:template>
</xsl:transform>

我当前的输出是

<hmtl>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>New Version!</title>
   </head>
   <ol class="eng-orderedlist orderedlist">

      <li class="item">
        <div class="para">
          <span class="item-num">(1)</span>This is first list item)
        </div>
      </li>

      <div class="x">179</div>

      <li class="item">
        <div class="para">
          <span class="item-num">(2)</span>This is second)
        </div>
      </li>     
      <li class="item">
        <div class="para">
          <span class="item-num">(3)</span>This is third)
        </div>
      </li>     
   </ol>
</hmtl>

但我的预期输出是

<hmtl>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>New Version!</title>
   </head>
   <ol class="eng-orderedlist orderedlist">
     <li class="item">
       <div class="para">
         <span class="item-num">(1)</span>This is first list item)
       </div>
     </li>
   </ol>

   <div class="x">179</div>

   <ol class="eng-orderedlist orderedlist">
     <li class="item">
       <div class="para">
         <span class="item-num">(2)</span>This is second)
       </div>
     </li>

     <li class="item">
       <div class="para">
         <span class="item-num">(3)</span>This is third)
       </div>
     </li>
   </ol>
</hmtl>

div class="x"上方的预期输出中,您可以看到<ol>已关闭,在打印div class="x"后,它会重新打开(<ol class="eng-orderedlist orderedlist">),请告诉我们我错了,如何解决它。

这是工作演示

Demo

1 个答案:

答案 0 :(得分:1)

如果<star.page>将在标签下,那么您甚至不需要xsl:choose。虽然这个xslt可以用更清洁,更有效的方式编写,但这是目前最小的改动:

<xsl:template match="star.page">
    <xsl:choose>
        <xsl:when test="name(..) = 'label' and name(../../..) = 'list' ">

编辑1: 虽然上述更改可行,但您可以使用更清晰的方式重写整个内容:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes"
        encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <hmtl>
            <head>
                <title>New Version!</title>
            </head>
            <xsl:apply-templates/>
        </hmtl>
    </xsl:template>

    <xsl:template name="orderedlist" match="list">
        <ol class="eng-orderedlist orderedlist">
            <xsl:apply-templates select="list.item"/>
        </ol>
    </xsl:template>

    <xsl:template name="orderitem" match="list.item">
        <xsl:apply-templates select="label/star.page"/>
        <li class="item">
            <div class="para">
                <span class="item-num">
                   <xsl:for-each select="label/text()">
                       <xsl:value-of select="."/>
                   </xsl:for-each>
                </span>
                <xsl:for-each select="text()">
                   <xsl:value-of select="."/>
                </xsl:for-each>
            </div>
        </li>
    </xsl:template>

    <xsl:template match="label/star.page">
        <xsl:text disable-output-escaping="yes">&lt;/ol&gt;</xsl:text>
        <div class="x">
            <xsl:value-of select="."/>
        </div>
        <xsl:text disable-output-escaping="yes">&lt;ol class="eng-orderedlist orderedlist"&gt;</xsl:text>
    </xsl:template>

</xsl:transform>

Edit2:已更新以包含标签

的所有文本节点