如何使用XSLT 2.0基于字符串中的整数检索节点?

时间:2011-09-16 09:56:15

标签: xml xslt xpath linq-to-xml

这是我的XML文档:

<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:body>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading1" />
            </w:ppr>
            <w:r>
                <w:t>Para1</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading2" />
            </w:ppr>
            <w:r>
                <w:t>Para2</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading3" />
            </w:ppr>
            <w:r>
                <w:t>Para3</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading4" />
            </w:ppr>
            <w:r>
                <w:t>Para4</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading1" />
            </w:ppr>
            <w:r>
                <w:t>Para5</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading3" />
            </w:ppr>
            <w:r>
                <w:t>Para6</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading4" />
            </w:ppr>
            <w:r>
                <w:t>Para7</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading2" />
            </w:ppr>
            <w:r>
                <w:t>Para8</w:t>
            </w:r>
        </w:p>
        <!-- This is my Current Node -->
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading3" />
            </w:ppr>
            <w:r>
                <w:t>Para9</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:ppr>
                <w:pstyle w:val="Heading1" />
            </w:ppr>
            <w:r>
                <w:t>Para10</w:t>
            </w:r>
        </w:p>
    </w:body>
</w:document>

因此,在阅读每个元素时,我想检查w:val的属性w:ppr/w:pstyle。例如,在上面的文件中,第一个w:p包含w:ppr/w:pstyle/@w:val个属性值Heading1。所以,对于第一个w:p,我不关心任何事情,只是接受它。之后,采用此w:p

  1. 我想拆分属性值Heading1,以便在标题后检索字符串。所以,现在我们得到1。然后,在读取下一个w:p时,应用相同的逻辑来分割当前属性值。所以,在这种情况下,我们有2。现在,我想将此当前值2与之前的值1进行比较。
  2. 如果小于之前的值,则只选择当前的w:p。否则,不要做任何事情。
  3. 对所有w:p节点应用上述步骤1和2。所以,在我的情况下,我想只选择以下w:p个节点。

    示例输出节点是(完全整个w:p节点):

    <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
        <w:body>
            <w:p>
                <w:ppr>
                    <w:pstyle w:val="Heading1" />
                </w:ppr>
                <w:r>
                    <w:t>Para1</w:t>
                </w:r>
            </w:p>
            <w:p>
                <w:ppr>
                    <w:pstyle w:val="Heading1" />
                </w:ppr>
                <w:r>
                    <w:t>Para5</w:t>
                </w:r>
            </w:p>
            <w:p>
                <w:ppr>
                    <w:pstyle w:val="Heading2" />
                </w:ppr>
                <w:r>
                    <w:t>Para8</w:t>
                </w:r>
            </w:p>
            <w:p>
                <w:ppr>
                    <w:pstyle w:val="Heading1" />
                </w:ppr>
                <w:r>
                    <w:t>Para10</w:t>
                </w:r>
            </w:p>
        </w:body>
    </w:document>
    

1 个答案:

答案 0 :(得分:2)

我相信你所说的是当相关的 w:val 属性大于 w:val时你想忽略 w:p 节点之前 w:p 的元素(存在的位置)。

在XPath术语中,......

number(substring-after(w:ppr/w:pstyle/@w:val, 'Heading'))
>= number(substring-after(preceding-sibling::w:p[1]/w:ppr/w:pstyle/@w:val, 'Heading'))  

这是完整的XSLT,它是身份转换,有额外的情况来匹配这样的 w:p 节点并忽略它们:

<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
   <xsl:output method="xml" indent="yes"/>

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

   <xsl:template match="w:p
   [
      preceding-sibling::w:p[1] 
      and 
         number(substring-after(w:ppr/w:pstyle/@w:val, 'Heading')) 
         >= number(substring-after(preceding-sibling::w:p[1]/w:ppr/w:pstyle/@w:val, 'Heading'))   
   ]">
   </xsl:template>

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

   <xsl:template match="comment()" />
</xsl:stylesheet>

应用于输入样本时,会生成以下输出:

<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
   <w:body>
      <w:p>
         <w:ppr>
            <w:pstyle w:val="Heading1"/>
         </w:ppr>
         <w:r>
            <w:t>Para1</w:t>
         </w:r>
      </w:p>
      <w:p>
         <w:ppr>
            <w:pstyle w:val="Heading1"/>
         </w:ppr>
         <w:r>
            <w:t>Para5</w:t>
         </w:r>
      </w:p>
      <w:p>
         <w:ppr>
            <w:pstyle w:val="Heading2"/>
         </w:ppr>
         <w:r>
            <w:t>Para8</w:t>
         </w:r>
      </w:p>
      <w:p>
         <w:ppr>
            <w:pstyle w:val="Heading1"/>
         </w:ppr>
         <w:r>
            <w:t>Para10</w:t>
         </w:r>
      </w:p>
   </w:body>
</w:document>