【问题标题】:Using XML and XSLT to format my study notes使用 XML 和 XSLT 格式化我的学习笔记
【发布时间】:2013-03-21 12:56:45
【问题描述】:

我想要一种方法来格式化我的学习笔记,获取输入文件并输出干净的 HTML 文件。我今天自学了基本的 XML 和 XSTL(并且具备 HTML 和 CSS 的先验知识)来完成此任务。所以我会有一个带有注释内容的简单 XML 文件,如下所示:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?> 
<root>
  <heading>Programming Fundamentals 48023</heading>
  <section>
    <subheading>Classes and Objects</subheading>
    <point>Something about classes</point>
    <point>Some else about classes</point>
    <codeBlock>
      <text>How to create an instance of a class</text>
      <code>Class class = new Class();</code>
    </codeBlock>
    <point>Something about objects</point>
    . . .
  </section>
  <section>
    <subheading>Methods</subheading>
    <point>Something about methods</point>
    <codeBlock>
      <text>How to define a method</text>
      <code>modifiers returnType methodName() { . . . }</code>
    </codeBlock>
    . . .
  </section>
  . . .
</root>  

XML 文档应该将我的笔记分成任意数量的部分,每个部分都有一个副标题,以及任意数量的点和不同格式的代码块的点。

然后,为了格式化 XML 文档,有一个 XSLT 样式表(带有 HTML 和 CSS 等),看起来有点像这样:

<?xsl version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
  <head>
    <title><xsl:value-of select="root/heading" /></title>
    <style>
      body {font-family:Tahoma; }
      div {width:800px; margin-left:auto; margin-right:auto; }
      h1 {color:#6FA5FD; border-bottom: 1px dotted #333333; text-indent:64px; }
      h2 {color:#6FA5FD; border-bottom: 1px dotted #333333; text-indent:96px; }
      pre {width:640px; border-style:dotted; border-width:1px; border-color:#333333; background-color:#CCCCFF; }
      ul {list-style-type:square; color:#6FA5FD; }
      li span {color:#000000; font-size:10; }
    </style>
  </head>
  <body>
    <div>
<!-- - - - - - - - - CONTENT STARTS HERE - - - - - - - - -->

<h1><xsl:value-of select="root/heading" /></h1>
<xsl:for-each select="root/section">
  <h2><xsl:value-of select="subheading" /></h2>
  <xsl:for-each select="point">
      <ul>
        <li><span>
          <xsl:value-of select="." />
        </span></li>
      </ul>
  </xsl:for-each>
  <xsl:for-each select="codeBlock">
      <ul>
        <li><span> <xsl:value-of select="./text" />
          <pre> <xsl:value-of select="./code" /> </pre>
        </span></li>
      </ul>
  </xsl:for-each>
</xsl:for-each>

<!-- - - - - - - - - CONTENT ENDS HERE - - - - - - - - -->
    </div>
  </body>
</html>
</xsl:template>
</xsl:stylesheet>  

所以 XML 元素变成了格式化的 HTML 元素,XML 元素变成了格式化的 HTML 元素。这很棒。然后 XML 标记将点点和代码块组合在一起,点点就变成了带有蓝色项目符号和黑色文本的列表项,并且代码块被格式化为 HTML 元素。

不过,我遇到了一些问题:
- 我没有办法让点具有不同程度的缩进。所以我不能有一个点,比如说,“类”,然后在那个点下面有几个点,稍微缩进,在一个点上讨论什么是类,在另一个点上命名约定,等等。我猜该解决方案与制作一些新的 XML 元素有关,例如 point2,其格式为:

    • 要点

而不是
  • 要点

(导致缩进的额外 HTML 元素)。
- 如果在我的 XML 文档中,我以特定的顺序定义了各种点和代码块(例如,点、点、代码块、点、代码块、点),那么在 XSLT 样式表完成其工作后生成的 HTML 文件将包含所有内容这些点聚集在一起,然后是所有的代码块(比如,点、点、点、点、代码块、代码块)。我明白为什么会这样;我的 XSLT 文档循环遍历所有 XML 元素,然后遍历所有 XML 元素。我猜这个解决方案与循环遍历一个元素的所有子节点有关,如果下一个元素是一个元素,则输出一件事,如果下一个元素是一个元素,则输出另一件事。

有什么想法吗?随意建议对 XML 或 XSLT 文档进行重组。也许我应该使用属性进行缩进或区分点和代码块?

谢谢!!

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    您遇到的问题是避免for-each 并使用模板的一个很好的理由,如下所示:

    <?xsl version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:strip-space elements="*" />
      <xsl:output indent="yes" omit-xml-declaration="yes" />
      <xsl:template match="/">
        <html>
          <head>
            <title>
              <xsl:value-of select="root/heading" />
            </title>
            <style>
              body {font-family:Tahoma; }
              div {width:800px; margin-left:auto; margin-right:auto; }
              h1 {color:#6FA5FD; border-bottom: 1px dotted #333333; text-indent:64px; }
              h2 {color:#6FA5FD; border-bottom: 1px dotted #333333; text-indent:96px; }
              pre {width:640px; border-style:dotted; border-width:1px; 
                   border-color:#333333; background-color:#CCCCFF; }
              ul {list-style-type:square; color:#6FA5FD; }
              li span {color:#000000; font-size:10; }
            </style>
          </head>
          <body>
            <div>
              <!-- - - - - - - - - CONTENT STARTS HERE - - - - - - - - -->
    
              <h1>
                <xsl:value-of select="root/heading" />
              </h1>
              <xsl:apply-templates select="root/section" />
    
              <!-- - - - - - - - - CONTENT ENDS HERE - - - - - - - - -->
            </div>
          </body>
        </html>
      </xsl:template>
    
      <xsl:template match="section">
        <h2>
          <xsl:value-of select="subheading" />
        </h2>
    
        <xsl:apply-templates select="." mode="list" />
      </xsl:template>
    
      <xsl:template match="*[point or codeBlock]" mode="list">
        <ul>
          <xsl:apply-templates select="point | codeBlock" />
        </ul>
      </xsl:template>
      <xsl:template match="*" mode="list" />
    
      <xsl:template match="point">
        <li>
          <span>
            <xsl:apply-templates select="text()" />
          </span>
          <xsl:apply-templates select="." mode="list" />
        </li>
      </xsl:template>
    
      <xsl:template match="codeBlock">
        <li>
          <span>
            <xsl:value-of select ="text" />
            <pre>
              <xsl:value-of select ="code" />
            </pre>
          </span>
        </li>
      </xsl:template>
    </xsl:stylesheet>
    

    我还包括上面的更改来处理多级点,所以你可以这样做:

    <point>
      I have a point.
      <point>
        This is a sub point
        <point>With a sub-sub point beneath it</point>
      </point>
      <point>This is just a sub point</point>
    </point>
    

    生成的 XML 将具有嵌套的 LI 和 UL:

    <li>
      <span>
        I have a point.
      </span>
      <ul>
        <li>
          <span>
            This is a sub point
          </span>
          <ul>
            <li>
              <span>With a sub-sub point beneath it</span>
            </li>
          </ul>
        </li>
        <li>
          <span>This is just a sub point</span>
        </li>
      </ul>
    </li>
    

    【讨论】:

    • 我很敬畏...这一切都完美无缺!感谢您的及时回复!我现在正在通读它并试图理解它 - 我也会看一些模板教程。再次感谢!
    最近更新 更多