模板模式循环行为

时间:2018-02-20 09:47:01

标签: html xml xslt transformation

我想通过xslt转换从xml生成一个简单的树结构。

xml源看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="style.xslt"?>
<root>
    <pi>
        <id>P1</id>
        <s>
            <sc>
                <id>SC1</id>
                <si>
                    <id>SI1</id>
                </si>
                <sc>
                    <id>SC2</id>
                    <si>
                        <id>SI2</id>
                    </si>
                    <si>
                        <id>SI3</id>
                    </si>
                </sc>
            </sc>
            <sc>
                <id>SC3</id>
                <si>
                    <id>SI4</id>
                </si>
            </sc>
            <si>
                <id>SI6</id>
            </si>
        </s>
    </pi>
</root>

这是我的xslt代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" indent="yes"/>
    <xsl:template match="xsl:stylesheet"/>
    <xsl:template match="/">
        <html>
            <head>
                <meta charset="utf-8"/>
                <title> Test </title>
            </head>
            <body>
                <h1> Test </h1>
                <xsl:for-each select=".">
                    <xsl:call-template name="PH"/>
                    <div>
                        <xsl:call-template name="Structure"/>
                    </div>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
    <!-- Header -->
    <xsl:template name="PH" match="//pi">
        <div>
            <h2> PI </h2>
            <table>
                <tr>
                    <td>Identifier:</td>
                    <td>
                        <xsl:value-of select="//pi/id"/>
                    </td>
                </tr>
            </table>
        </div>
    </xsl:template>
    <!-- Structure -->
    <xsl:template name="Structure" match="//s">
        <div>Structure</div>
        <xsl:apply-templates select="//s/sc"/>
        <xsl:apply-templates select="//s/si"/>
    </xsl:template>
    <!-- Container -->
    <xsl:template match="//s/sc" mode="loop">
        <div><xsl:value-of select="id"/></div>
    </xsl:template>
    <xsl:template match="//sc/sc" mode="loop">
        <div><xsl:value-of select="id"/></div>
    </xsl:template>
    <!-- Item -->
    <xsl:template name="StructueItem" match="//s/si">
        <div><xsl:value-of select="id"/></div>
    </xsl:template>
    <xsl:template name="StructueItem1" match="//sc/si">
        <div><xsl:value-of select="id"/></div>
    </xsl:template>
</xsl:stylesheet>

我希望,生成的HTML中包含所有HTML标记和来自xml源的内容。但是转换结果中没有所有sc xml元素的周围div标记。

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <meta charset="utf-8">
      <title> Test </title>
   </head>
   <body>
      <h1> Test </h1>
      <div>
         <h2> PI </h2>
         <table>
            <tr>
               <td>Identifier:</td>
               <td>P1</td>
            </tr>
         </table>
      </div>
      <div>
         <div>Structure</div>
         SC1      
         <div>SI1</div>
         SC2
         <div>SI2</div>
         <div>SI3</div>
         SC3
         <div>SI4</div>
         <div>SI6</div>
      </div>
   </body>
</html>

我在哪里弄错了?

谢谢!

1 个答案:

答案 0 :(得分:0)

关于源XML的第一句话: 正如您希望<div>SI6</div>位于SC3之下,我认为

<si>
  <id>SI6</id>
</si>

应该&#34;向上移动&#34; - 位于上方的<sc>元素内。

我对你的剧本做了一些修改。

  1. 我移动了内容,而不是调用Structure模板 (有一点例外)到了通话地点。

  2. 当您拨打某些模板&#34;名称&#34; (而不是&#34;通过匹配&#34;), 我从中删除了match属性,以使脚本更清晰。

  3. 由于根节点只有一个,因此主模板中的for-each循环 (不需要匹配&#34; /&#34;)。

  4. 基本思路是,我从主模板应用模板 所有后代sc元素。

  5. 反过来,匹配sc的模板会首先打印自己的id元素 然后将模板应用于其子si元素。

  6. 所以整个脚本可能如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:output method="html"
        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
        doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>
    
      <xsl:template match="/">
        <html>
          <head>
            <meta charset="utf-8"/><title> Test </title>
          </head>
          <body>
            <h1> Test </h1>
            <xsl:call-template name="PH"/>
            <div>
              <div>Structure</div>
              <xsl:apply-templates select="//sc"/>
            </div>
          </body>
        </html>
      </xsl:template>
    
      <!-- Header -->
      <xsl:template name="PH">
        <div>
          <h2> PI </h2>
          <table>
            <tr>
              <td>Identifier:</td>
              <td><xsl:value-of select="//pi/id"/></td>
            </tr>
          </table>
        </div>
      </xsl:template>
    
      <xsl:template match="sc">
        <xsl:value-of select="id"/>
        <xsl:apply-templates select="si"/>
      </xsl:template>
    
      <xsl:template match="si">
        <div>
          <xsl:value-of select="id"/>
        </div>  
      </xsl:template>
    </xsl:stylesheet>
    

    有关工作示例,请参阅http://xsltransform.net/3MEbY6F 它适用于 Xalan Saxon 引擎。