使用XML和XSLT格式化我的学习笔记

时间:2013-03-21 12:56:45

标签: xml xslt

我想要一种格式化学习笔记的方法,输入一个输入文件并输出一个干净的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元素中被格式化。

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

          
              
    • POINT
    •       
        

而不是     
          
  • POINT
  •     

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

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

三江源!!

1 个答案:

答案 0 :(得分:0)

您遇到的聚合是避免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>