如何在XML之外查找章节号

时间:2013-12-06 14:13:57

标签: xml xslt

我正在编写XML和XSL来创建基于书籍的HTML文档。所有文件都称为 chapter-1.xml chapter-2.xml 等。每章的标题将以#章节开头,后面是章节标题。这些章节将由不同的人编写,因此每章必须在每个xml文件中。

XML:

<chapter title="This is the first chapter">
<paragraph title="Start">Blablabla</paragraph>
</chapter>

XSL:

<xsl:for-each select="chapter">
    <h1><xsl:value-of select="current()/@title"/></h1>
    <xsl:for-each select="chapter">
        <h2><xsl:value-of select="current()/@title"/></h2><br><br>
        <xsl:value-of select="current()" />
    </xsl:for-each>
</xsl:for-each>

我有一个PHP来创建HTML:

<?php
# LOAD XML FILE
$XML = new DOMDocument();
$XML->load('chapter-1.xml');

$xslt = new XSLTProcessor();
$XSL = new DOMDocument();
$XSL->load('chapter.xsl');
$xslt->importStylesheet( $XSL );
print $xslt->transformToXML( $XML );
?>

我希望这在HTML中显示为“1.这是第一章”。无论如何在没有使用标签中的其他属性的情况下解决这个问题?每个文档只有1个章节标记。有没有办法用CSS解决这个问题,或者从文件名中获取章节号?

我还需要为所有带编号的章节创建一个目录。

2 个答案:

答案 0 :(得分:0)

由于你的代码没有任何意义,我担心,这是如何解决像你这样的问题的一般想法。

控制您的输入

chapter节点提供单独的XML文件是不方便的。因此,如果您自己生成这些文件,请确保在同一XML文件中生成所有chapter元素,例如:像这样:

<chapters>
 <chapter title="This is the first chapter">
    <paragraph title="Start">Blablabla</paragraph>
 </chapter>
 <chapter title="xy">
    <paragraph title="Start">Blablabla</paragraph>
 </chapter>
</chapters>

最明智的方法是在此阶段引入编号属性。如果您无法更改输入结构,请使用XSLT的document()函数在转换中包含多个XML文件。

使用xsl:for-eachposition()生成编号

如果您设法将元素组合在一个文件中,请使用属性对它们进行编号。例如,

<xsl:variable name="chaps" select="//chapter"/>

<xsl:template match="chapters">
   <xsl:for-each select="$chaps">
      <xsl:copy>
         <xsl:attribute name="nr">
           <xsl:value-of select="position()"/>
         </xsl:attribute>
      </xsl:copy>
   </xsl:for-each>
</xsl:template>

或者,您也可以使用xsl:number

Q&amp; A

  

无论如何要解决这个问题而不使用其中的其他属性   标记

是的,使用这两种方法之一直接在HTML输出中生成编号。

  

有没有办法用CSS解决这个问题,或者通过获取章节   文件名中的数字左右?

尝试在CSS中解决这个问题是一个坏主意。 CSS是关于文档的样式,而不是关于更改内容。我还建议在转换文档时不要依赖文件名。

答案 1 :(得分:0)

假设您有一个名为“toc.xml”的文档,该文档与样式表位于同一目录中,如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<toc>
<chapter num="1" title="First Chapter"/>
<chapter num="2" title="Second Chapter"/>
<chapter num="3" title="Inserted Chapter"/>
<chapter num="4" title="Third Chapter"/>
<chapter num="5" title="Last Chapter"/>
<chapter num="6" title="Last Minute Chapter"/>
</toc>

假设你的'chapter-3.xml'文件看起来像这样:

<?xml version="1.0" encoding="utf-8" ?>
<chapter title="Third Chapter">
    <paragraph title="Start">Lorem ipsum ... </paragraph>
    <paragraph title="End">...nota bene.</paragraph>
</chapter>

现在,应用以下XSLT样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html" encoding="utf-8"/>

<xsl:variable name="toc" select="document('toc.xml')/toc" />

<xsl:template match="/">
<html>
<body>

<xsl:variable name="chapTitle" select="chapter/@title" />
<xsl:variable name="chapNum" select="$toc/chapter[@title=$chapTitle]/@num"/>

<h1><xsl:value-of select="concat($chapNum, '. ', $chapTitle)"/></h1>

<xsl:for-each select="chapter/paragraph">
    <h2><xsl:value-of select="@title"/></h2>
    <p><xsl:value-of select="."/></p>
</xsl:for-each>
<h4><xsl:value-of select="concat('Next chapter: ', $toc/chapter[$chapNum+1]/@title)"/></h4>

</body>
</html>
</xsl:template>
</xsl:stylesheet>

会产生这样的结果:

<html>
   <body>
      <h1>4. Third Chapter</h1>
      <h2>Start</h2>
      <p>Lorem ipsum ... </p>
      <h2>End</h2>
      <p>...nota bene.</p>
      <h4>Next chapter: Last Chapter</h4>
   </body>
</html>