计算忽略空白节点的节点

时间:2015-06-09 10:54:04

标签: xslt xslt-2.0

我是以下的XML。

案例1

<body>
    <nd>
        <pnn>1.1</pnn>
        <h1>PART 54</h1>
        <ti>Construction</ti>
    </nd>
    <nd>
        <h1>PART 54</h1>
        <h2>I INTRODUCT</h2>
        <ti>Time</ti>
    </nd>
    <nd>
        <h1>PART 54</h1>
        <h2>I INTRODUCT</h2>
        <ti>Power</ti>
    </nd>
    <nd>
        <h1>PART 54</h1>
        <h2>II APPLICATIONS</h2>
        <ti>Filing</ti>
    </nd>
</body>

案例2

<body>
    <nd>
        <pnn>1.1</pnn>
        <h1>PART 54</h1>
        <h2>I INTRODUCT</h2>
        <ti>Construction</ti>
    </nd>
    <nd>
        <h1>PART 54</h1>
        <h2>I INTRODUCT</h2>
        <ti>Time</ti>
    </nd>
    <nd>
        <h1>PART 54</h1>
        <h2>II APPLICATIONS</h2>
        <ti>Filing</ti>
    </nd>
</body>

以及下面的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 select="body"></xsl:apply-templates>
      </hmtl>
    </xsl:template>

    <xsl:template match="body">
         <xsl:for-each select="nd">
            <xsl:apply-templates select = "."/>
        </xsl:for-each>
    </xsl:template>
   <xsl:template match="pnn"/>
   <xsl:template match="h1"/>
   <xsl:template match="h2"/>
   <xsl:template match="ti"/>
<xsl:variable name="FinalChap">
        <xsl:value-of select="substring-before((//pnn)[1],'.')"/>
    </xsl:variable>
    <xsl:variable name="FinalChn">
        <xsl:value-of select="$FinalChap"/>
    </xsl:variable>
    <xsl:variable name="Finalchapternumber">
        <xsl:value-of select="format-number($FinalChn,'00')"/>
    </xsl:variable>

    <xsl:template name="section" match="nd">
        <xsl:variable name="count">
            <xsl:number count="nd" level="any"/>
        </xsl:variable>
        <xsl:variable name="classname">
            <!--Get name attribute of current node -->
            <xsl:value-of select="concat('section-sect','1')"/>
        </xsl:variable>
        <xsl:variable name="classname1">
            <!--Get name attribute of current node -->
            <xsl:value-of select="concat('section-sect','2')"/>
        </xsl:variable>
        <xsl:variable name="classname2">
            <!--Get name attribute of current node -->
            <xsl:value-of select="concat('section-sect','3')"/>
        </xsl:variable>

        <!--Create a string variable by concat string method  -->
        <xsl:variable name="sectionname">
            <xsl:value-of select="concat('CH_',$Finalchapternumber,'-SEC-', $count)"/>
        </xsl:variable>
            <div class="{$classname}">
            <xsl:if test="./h2 and not(preceding::h2[1]/text() = ./h2/text())">
                <a name="{$sectionname}"> </a>
                <div class="section-title">
                    <xsl:if test="not(preceding::h2[1]/text() = ./h2/text())">
                        <xsl:apply-templates select="h2" mode="section"/>
                    </xsl:if>
                </div>
            </xsl:if>
            <xsl:if test="not(lower-case(./ti/text()) = lower-case(./h2/text()))">
                <xsl:if test="./ti">
                    <div class="{$classname2}">
                        <xsl:apply-templates select="ti" mode="section"/>
                    </div>
                </xsl:if>
            </xsl:if>
            <xsl:apply-templates select="child::node()[not(self::h2|self::ti)]"/>
        </div>
    </xsl:template>
    <xsl:template match="ti" mode="section">
        <xsl:apply-templates select="./node()[1][self::page]" mode="first"/>
        <xsl:variable name="sectionnum">
            <xsl:number count="nd" level="any"/>
        </xsl:variable>
        <a name="CH_{$Finalchapternumber}-SEC-{$sectionnum}"/>
        <div class="section-title">
            <xsl:apply-templates/>
        </div>
    </xsl:template>
    <xsl:template match="h2" mode="section">
        <div class="section-title">
            <xsl:apply-templates select="child::node()[not(self::fnt)]"/>
        </div>
    </xsl:template>


</xsl:transform>

这里我试图根据条件增加节号。计数应该完成,如果没有节点(这里h2<a name="CH_01-SEC-XX"></a>应该被忽略我能够使用<xsl:if test="./h2 and not(preceding::h2[1]/text() = ./h2/text())">来做,但挑战我是&#39}。面对的是count并不是忽略它。

当前输出。案例1

<div class="section-sect1">
    <a name="CH_01-SEC-1"/>
    <div class="section-title">
        <div class="section-title">I INTRODUCT</div>
    </div>
    <div class="section-sect3">
        <a name="CH_01-SEC-1"/>
        <div class="section-title">Construction</div>
    </div>
</div>
<div class="section-sect1">
    <div class="section-sect3">
        <a name="CH_01-SEC-2"/>
        <div class="section-title">Time</div>
    </div>
</div>
<div class="section-sect1">
    <div class="section-sect3">
        <a name="CH_01-SEC-3"/>
        <div class="section-title">Power</div>
    </div>
</div>
<div class="section-sect1">
    <a name="CH_01-SEC-4"/>
    <div class="section-title">
        <div class="section-title">II APPLICATIONS</div>
    </div>
    <div class="section-sect3">
        <a name="CH_01-SEC-4"/>
        <div class="section-title">Filing</div>
    </div>
</div>

预期输出案例1

<div class="section-sect1">
    <a name="CH_01-SEC-1"/>
    <div class="section-title">
        <div class="section-title">I INTRODUCT</div>
    </div>
    <div class="section-sect3">
        <a name="CH_01-SEC-2"/>
        <div class="section-title">Construction</div>
    </div>
</div>
<div class="section-sect1">
    <div class="section-sect3">
        <a name="CH_01-SEC-3"/>
        <div class="section-title">Time</div>
    </div>
</div>
<div class="section-sect1">
    <div class="section-sect3">
        <a name="CH_01-SEC-4"/>
        <div class="section-title">Power</div>
    </div>
</div>
<div class="section-sect1">
    <a name="CH_01-SEC-5"/>
    <div class="section-title">
        <div class="section-title">II APPLICATIONS</div>
    </div>
    <div class="section-sect3">
        <a name="CH_01-SEC-6"/>
        <div class="section-title">Filing</div>
    </div>
</div>

当前输出案例2

<div class="section-sect1"><a name="CH_01-SEC-1"></a><div class="section-title">
         <div class="section-title">I INTRODUCT</div>
      </div>
      <div class="section-sect3"><a name="CH_01-SEC-1"></a><div class="section-title">Construction</div>
      </div>
      </div>
   <div class="section-sect1">
      <div class="section-sect3"><a name="CH_01-SEC-2"></a><div class="section-title">Time</div>
      </div>
   </div>
   <div class="section-sect1"><a name="CH_01-SEC-3"></a><div class="section-title">
         <div class="section-title">II APPLICATIONS</div>
      </div>
      <div class="section-sect3"><a name="CH_01-SEC-3"></a><div class="section-title">Filing</div>
      </div>
   </div>

预期输出案例2

<div class="section-sect1">
    <a name="CH_01-SEC-1"/>
    <div class="section-title">
        <div class="section-title">I INTRODUCT</div>
    </div>
    <div class="section-sect3">
        <a name="CH_01-SEC-2"/>
        <div class="section-title">Construction</div>
    </div>
</div>
<div class="section-sect1">
    <div class="section-sect3">
        <a name="CH_01-SEC-3"/>
        <div class="section-title">Time</div>
    </div>
</div>
<div class="section-sect1">
    <a name="CH_01-SEC-4"/>
    <div class="section-title">
        <div class="section-title">II APPLICATIONS</div>
    </div>
    <div class="section-sect3">
        <a name="CH_01-SEC-5"/>
        <div class="section-title">Filing</div>
    </div>
</div>

在当前输出中有重复CH_01-SEC-1有人可以告诉我如何将其变成一系列1...n

这是一个有效的DEmo

由于

1 个答案:

答案 0 :(得分:1)

怎么样......

<xsl:transform
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:variable name="FinalChap">
  <xsl:value-of select="format-number( xs:integer( substring-before((/body/nd/pnn)[1],'.')), '00')"/>
</xsl:variable>

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

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

<xsl:template match="text()|processing-instruction()|comment()|@*" />

<xsl:template match="body">
  <xsl:for-each-group select="nd" group-adjacent="h2/text()">
    <xsl:variable name="group-position" select="position()" />
    <xsl:for-each select="current-group()">
     <xsl:call-template name="nd">
      <xsl:with-param name="group-position" select="$group-position" />
      <xsl:with-param name="is-head" select="position() eq 1" as="xs:boolean" />
     </xsl:call-template>  
    </xsl:for-each>  
  </xsl:for-each-group>
</xsl:template>

<xsl:template name="nd">
 <xsl:param name="group-position" select="1" as="xs:integer" />
 <xsl:param name="is-head" select="true()" as="xs:boolean" />

 <div class="section-sect1">
  <xsl:if test="$is-head"> 
   <xsl:call-template name="a-link">
    <xsl:with-param name="group-position" select="$group-position" />
    <xsl:with-param name="delta" select="0" as="xs:integer" />
   </xsl:call-template>  
   <div class="section-title">
    <div class="section-title"><xsl:value-of select="h2" /></div>
   </div>
   </xsl:if>  
  <div class="section-sect3">
    <xsl:call-template name="a-link">
     <xsl:with-param name="group-position" select="$group-position" />
     <xsl:with-param name="delta" select="1" as="xs:integer" />
    </xsl:call-template>  
    <div class="section-title"><xsl:value-of select="ti" /></div>
  </div>
 </div>
</xsl:template>


<xsl:template name="a-link">
 <xsl:param name="group-position" select="1" as="xs:integer" />
 <xsl:param name="delta" select="0" as="xs:integer" />
  <a name="CH_{$FinalChap}-SEC-{$group-position + count(preceding-sibling::nd) + $delta}" /> 
</xsl:template>  

</xsl:transform>

以上转换,应用于输入文档...

<body>
    <nd>
        <pnn>1.1</pnn>
        <h1>PART 54</h1>
        <h2>I INTRODUCT</h2>
        <ti>Construction</ti>
    </nd>
    <nd>
        <h1>PART 54</h1>
        <h2>I INTRODUCT</h2>
        <ti>Time</ti>
    </nd>
    <nd>
        <h1>PART 54</h1>
        <h2>I INTRODUCT</h2>
        <ti>Power</ti>
    </nd>
    <nd>
        <h1>PART 54</h1>
        <h2>II APPLICATIONS</h2>
        <ti>Filing</ti>
    </nd>
</body>

...产生输出文件......

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>New Version from Sean!</title>
</head>
<div class="section-sect1">
    <a name="CH_01-SEC-1"/>
    <div class="section-title">
        <div class="section-title">I INTRODUCT</div>
    </div>
    <div class="section-sect3">
        <a name="CH_01-SEC-2"/>
        <div class="section-title">Construction</div>
    </div>
</div>
<div class="section-sect1">
    <div class="section-sect3">
        <a name="CH_01-SEC-3"/>
        <div class="section-title">Time</div>
    </div>
</div>
<div class="section-sect1">
    <div class="section-sect3">
        <a name="CH_01-SEC-4"/>
        <div class="section-title">Power</div>
    </div>
</div>
<div class="section-sect1">
    <a name="CH_01-SEC-5"/>
    <div class="section-title">
        <div class="section-title">II APPLICATIONS</div>
    </div>
    <div class="section-sect3">
        <a name="CH_01-SEC-6"/>
        <div class="section-title">Filing</div>
    </div>
</div>
</html>

说明

body模板使用xsl:for-each-group按共同的h2(h2标题)对nd元素进行分组。 xsl:for-each-group序列构造函数调用nd模板按顺序处理每个nd元素,并向其传递组号,以及此nd是否为第一个('头')小组。

我从您的示例输出中推断出,每个组的头部nd会产生关于该组的额外内容,包括额外的a-link。

a-link的编号(例如CH_01-SEC-4中的4)等于前面的nd的数量加上组编号,如果我们不是头部,则加上额外的1。

替代解决方案

正如有许多方法可以给猫皮肤一样,有一些安静的解决方案可以同样有效。您可以使用完整推送设计,而不是分组。头节点(<div class="section-title">)的额外内容可以使用模板模式上的谓词来实现,将该h2与先前的h2进行比较。并且可以通过微流水线来实现a-links的校正数量。