2016-06-09 53 views
1

我正在尝试使用XSL将XML文档转换为HTML页面。我有95%的路,但我遇到了包含文本和其他节点必须按顺序显示的节点的问题。XSL XPath按顺序在每个循环中选择混合文本和节点?

XML:

<chapter title="Chapter 1" reqlen="2500"> 
    <section title="The Quick Brown Fox"> 
     <subsection title="null"> 
      <keywords>foo,bar</keywords> 
      <body> 
       <p> 
        Lorem ipsum <b>dolor sit amet</b>, consectetur adipiscing elit. 
     Maecenas sed pretium nunc. 
        <int>foo/bar/qux</int> 
        Proin tincidunt sapien dolor, posuere varius dui efficitur ac. 
        <ext>http://google.com/</ext> 
       </p> 
       <p> 
        Foo bar <b>doqux amet</b>, foo adipiscing elit. 
     Maecenas sed pretium nunc. 
        <int>foo/bar/qux</int> 
        Proin tincidunt sapien dolor, posuere varius dui efficitur ac. 
        <ext>http://google.com/</ext> 
       </p> 
      </body> 
      <note>Lorem ipsum</note> 
     </subsection> 
    </section> 
</chapter> 

XSL:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="stylesheet" version="1.0"> 
    <xsl:template match="xsl:stylesheet" /> 
    <xsl:template match="/chapter"> 
     <html> 
      <head> 
       <title> 
        <xsl:value-of select="@title" /> 
       </title> 
       <style type="text/css">body { 
      padding: 50px 10%; 
      }</style> 
      </head> 
      <body> 
       <h1> 
        <xsl:value-of select="@title" /> 
       </h1> 
       <xsl:for-each select="section"> 
        <xsl:if test="@title!='null'"> 
         <h2> 
          <xsl:value-of select="@title" /> 
         </h2> 
        </xsl:if> 
        <xsl:for-each select="subsection"> 
         <xsl:if test="@title!='null'"> 
          <h3> 
           <xsl:value-of select="@title" /> 
          </h3> 
         </xsl:if> 
         <xsl:for-each select="body/p"> 
          <p> 
           <xsl:value-of select="current()" /> 
          </p> 
         </xsl:for-each> 
        </xsl:for-each> 
       </xsl:for-each> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

这将导致以下HTML:

<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>Chapter 1</title> 
     <style type="text/css"> 
      body { 
      padding: 50px 10%; 
      } 
     </style> 
    </head> 
    <body> 
     <h1>Chapter 1</h1> 
     <h2>The Quick Brown Fox</h2> 
     <p> 
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
      Maecenas sed pretium nunc. 
      foo/bar/qux 
      Proin tincidunt sapien dolor, posuere varius dui efficitur ac. 
      http://google.com/ 
     </p> 
     <p> 
      Foo bar doqux amet, foo adipiscing elit. 
      Maecenas sed pretium nunc. 
      foo/bar/qux 
      Proin tincidunt sapien dolor, posuere varius dui efficitur ac. 
      http://google.com/ 
     </p> 
    </body> 
</html> 

的问题是,我想向<p></p>内变换某些标签节点。

内部<p>节点,可以有明文和节点<b></b><i></i><int></int><ext></ext>,和<cvc></cvc>的混合物。在这个级别之后永远不会嵌套,即<b></b>将只包含文本。

这是我想要的HTML:

<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>Chapter 1</title> 
     <style type="text/css"> 
      body { 
      padding: 50px 10%; 
      } 
     </style> 
    </head> 
    <body> 
     <h1>Chapter 1</h1> 
     <h2>The Quick Brown Fox</h2> 
     <p> 
      Lorem ipsum <strong>dolor sit amet</strong>, consectetur adipiscing elit. 
      Maecenas sed pretium nunc. 
      <a href="/foo/bar/qux">foo/bar/qux</a> 
      Proin tincidunt sapien dolor, posuere varius dui efficitur ac. 
      <a href="http://google.com/">http://google.com/</a> 
     </p> 
     <p>Foo bar <strong>doqux amet</strong>, foo adipiscing elit. 
      Maecenas sed pretium nunc. 
      <a href="/foo/bar/qux">foo/bar/qux</a> 
      Proin tincidunt sapien dolor, posuere varius dui efficitur ac. 
      <a href="http://google.com/">http://google.com/</a> 
     </p> 
    </body> 
</html> 

我已经尝试了不同的XPath功能,for-each循环,两者的混合物,但我无法弄清楚如何得到我想要的输出。我已经得到的最接近的是这个XSL:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="stylesheet" version="1.0"> 
    <xsl:template match="xsl:stylesheet" /> 
    <xsl:template match="/chapter"> 
     <html> 
      <head> 
       <title> 
        <xsl:value-of select="@title" /> 
       </title> 
       <style type="text/css">body { 
      padding: 50px 10%; 
      }</style> 
      </head> 
      <body> 
       <h1> 
        <xsl:value-of select="@title" /> 
       </h1> 
       <xsl:for-each select="section"> 
        <xsl:if test="@title!='null'"> 
         <h2> 
          <xsl:value-of select="@title" /> 
         </h2> 
        </xsl:if> 
        <xsl:for-each select="subsection"> 
         <xsl:if test="@title!='null'"> 
          <h3> 
           <xsl:value-of select="@title" /> 
          </h3> 
         </xsl:if> 
         <xsl:for-each select="body/p"> 
          <p> 
           <xsl:for-each select="text()"> 
            <xsl:value-of select="current()" /> 
           </xsl:for-each> 
           <xsl:for-each select="b"> 
            <strong> 
             <xsl:value-of select="current()" /> 
            </strong> 
           </xsl:for-each> 
           <xsl:for-each select="int"> 
            <a href="#"> 
             <xsl:value-of select="current()" /> 
            </a> 
           </xsl:for-each> 
           <xsl:for-each select="ext"> 
            <a href="#"> 
             <xsl:value-of select="current()" /> 
            </a> 
           </xsl:for-each> 
          </p> 
         </xsl:for-each> 
        </xsl:for-each> 
       </xsl:for-each> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

但HTML输出失灵:

<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>Chapter 1</title> 
     <style type="text/css"> 
      body { 
      padding: 50px 10%; 
      } 
     </style> 
    </head> 
    <body> 
     <h1>Chapter 1</h1> 
     <h2>The Quick Brown Fox</h2> 
     <p> 
      Lorem ipsum , consectetur adipiscing elit. 
      Maecenas sed pretium nunc. 
      Proin tincidunt sapien dolor, posuere varius dui efficitur ac. 
      <strong>dolor sit amet</strong><a href="#">foo/bar/qux</a><a href="#">http://google.com/</a> 
     </p> 
     <p> 
      Foo bar , foo adipiscing elit. 
      Maecenas sed pretium nunc. 
      Proin tincidunt sapien dolor, posuere varius dui efficitur ac. 
      <strong>doqux amet</strong><a href="#">foo/bar/qux</a><a href="#">http://google.com/</a> 
     </p> 
    </body> 
</html> 
+0

你需要学习如何使用模板规则。使用模板规则对XML树进行递归处理是使用XSLT的自然方式,对于处理混合内容特别重要。 –

回答

1

考虑这样的事情:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="xsl:stylesheet" /> 
    <xsl:template match="/chapter"> 
    <html> 
     <head> 
     <title> 
      <xsl:value-of select="@title" /> 
     </title> 
     <style type="text/css"> 
      body { 
      padding: 50px 10%; 
      } 
     </style> 
     </head> 
     <body> 
     <h1> 
      <xsl:value-of select="@title" /> 
     </h1> 
     <xsl:for-each select="section"> 
      <xsl:if test="@title!='null'"> 
      <h2> 
       <xsl:value-of select="@title" /> 
      </h2> 
      </xsl:if> 
      <xsl:for-each select="subsection"> 
      <xsl:if test="@title!='null'"> 
       <h3> 
       <xsl:value-of select="@title" /> 
       </h3> 
      </xsl:if> 
      <xsl:for-each select="body/p"> 
       <p> 
       <xsl:apply-templates/> 
       </p> 
      </xsl:for-each> 
      </xsl:for-each> 
     </xsl:for-each> 
     </body> 
    </html> 
    </xsl:template> 


    <xsl:template match="b"> 
    <strong> 
     <xsl:value-of select="."/> 
    </strong> 
    </xsl:template> 

    <xsl:template match="int"> 
    <a href="#"> 
     <xsl:value-of select="."/> 
    </a> 
    </xsl:template> 

    <xsl:template match="ext"> 
    <a href="#"> 
     <xsl:value-of select="."/> 
    </a> 
    </xsl:template> 

</xsl:stylesheet> 
+0

正是我在找什么,谢谢! –

+0

@DC_,欢迎您 –