两个连续节点的XSLT模板

时间:2014-04-25 09:02:04

标签: xml xslt xpath

我正在尝试使用XSLT转换以下HTML:

<html>
    <body>
        <h3 class="one">Text in one</h3>
        <h3 class="two">Text in two</h3>
        <p class="lorem">Paragraph 1.</p>
        <p class="lorem">Paragraph 2.</p>
        <p class="lorem">Paragraph 3.</p>
        <p class="lorem">Paragraph 4.</p>
        <p class="lorem">Paragraph 5.</p>
        <h3 class="three">Single heading</h3>
        <p class="ipsum">Paragraph 6.</p>
        <p class="ipsum">Paragraph 7.</p>
        <p class="ipsum">Paragraph 8.</p>
        <h3 class="one">Text in one 2</h3>
        <h3 class="two">Text in two 2</h3>
        <p class="ipsum">Paragraph 9.</p>
        <p class="ipsum">Paragraph 10.</p>
    </body>
</html>

<wrapper>
  <cmd>
    <p>Text in one</p>
    <p>Text in two</p>
  </cmd>
  <something>Paragraph 1.</something>
  <something>Paragraph 2.</something>
  <something>Paragraph 3.</something>
  <something>Paragraph 4.</something>
  <something>Paragraph 5.</something>
  <p>Single heading</p>
  <somethingelse>Paragraph 6.</somethingelse>
  <somethingelse>Paragraph 7.</somethingelse>
  <somethingelse>Paragraph 8.</somethingelse>
  <cmd>
    <p>Text in one 2</p>
    <p>Text in two 2</p>
  </cmd>
  <somethingelse>Paragraph 9.</somethingelse>
  <somethingelse>Paragraph 10.</somethingelse>
</wrapper>

我确实关注过XSLT:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <wrapper>
            <xsl:apply-templates select="html/body/*" />
        <xsl:text>&#xa;</xsl:text></wrapper>
    </xsl:template>

    <xsl:template match="p[@class='lorem']">
        <xsl:text>&#xa;</xsl:text><something>
            <xsl:value-of select="."/>
        </something>
    </xsl:template>

    <xsl:template match="p[@class='ipsum']">
        <xsl:text>&#xa;</xsl:text><somethingelse>
            <xsl:value-of select="."/>
        </somethingelse>
    </xsl:template>

    <xsl:template match="h3[@class='three']">
       <xsl:text>&#xa;</xsl:text><p>
            <xsl:value-of select="."/>
        </p>
    </xsl:template>

</xsl:stylesheet>

但是我不知道如何将它包装到<cmd>中以获得带有h3.one和h3.two的那两个片段:

<cmd>
    <p>Text in one</p>
    <p>Text in two</p>
</cmd>

<cmd>
    <p>Text in one 2</p>
    <p>Text in two 2</p>
</cmd>

1 个答案:

答案 0 :(得分:1)

请尝试以下样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

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

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


    <xsl:template match="h3[preceding-sibling::*[1][name()='h3']]">
        <cmd>
            <p><xsl:value-of select="preceding-sibling::*[1][name()='h3']"/></p>
            <p><xsl:value-of select="."/></p>
        </cmd>
    </xsl:template>

    <xsl:template match="h3[following-sibling::*[1][name()='h3']]"/>

    <xsl:template match="h3[not(following-sibling::*[1][name()='h3']) and not(preceding-sibling::*[1][name()='h3'])]">
        <p><xsl:value-of select="."/></p>
    </xsl:template>

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