【问题标题】:Detecting table element error in docbook 5.0 document检测 docbook 5.0 文档中的表格元素错误
【发布时间】:2016-12-13 14:20:54
【问题描述】:

我没有太多运气在我的previous post 中得到完整的答案。所以我再次尝试使用不同的方法。

如何使用table 检测以下文档手册中的错误:

$ cat article.xml
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<article xmlns="http://docbook.org/ns/docbook" version="5.0">
  <title>Title</title>
  <table>
    <caption>caption</caption>
    <tbody>
      <tr>
        <td rowspan="2">
          <para>my para</para>
        </td>
      </tr>
    </tbody>
  </table>
</article>

显然,由于我做了一个可重复的小示例,我知道错误在我的输入 docbook 文档中的位置,我的问题是关于可用于检测它们并有效跟踪它们的命令行工具(行号和可能的列偏移量)。

我只接受使用输入 docbook 5.0 (XML) 文档或输入格式对象(FO 文件)检测错误的答案。

答案应该在命令行工具系列中明确(使用软件“X”不是可接受的答案)。

理想情况下,我猜我可以简单地运行:

$ xmllint --nonet --noout --schema /usr/share/xml/docbook/schema/xsd/5.0/docbook.xsd article.xml
article.xml validates

$ jing /usr/share/xml/docbook/schema/rng/5.0/docbook.rng article.xml && echo "success"
success

我的 Debian GNU/Linux 系统 [*]


更新:我不是在寻找所有可能的 FO 问题的通用解决方案,我只是在寻找一种方法来跟踪冗长而复杂的&lt;table&gt; 元素中的问题。

[*]

$ xsltproc -o article.fo /usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl article.xml && fop article.fo article.pdf
Note: namesp. cut : stripped namespace before processing           Additional Protocols
Note: namesp. cut : processing stripped document                   Additional Protocols
Making portrait pages on USletter paper (8.5inx11in)
[WARN] FOUserAgent - The following feature isn't implemented by Apache FOP, yet: table-layout="auto" (on fo:table) (See position 2:30164)
[ERROR] FOP - Exception <org.apache.fop.apps.FOPException: org.apache.fop.fo.ValidationException: A table-cell is spanning more rows than available in its parent element.
javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: A table-cell is spanning more rows than available in its parent element.>org.apache.fop.apps.FOPException: org.apache.fop.fo.ValidationException: A table-cell is spanning more rows than available in its parent element.
javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: A table-cell is spanning more rows than available in its parent element.
    at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:288)
    at org.apache.fop.cli.InputHandler.renderTo(InputHandler.java:115)
    at org.apache.fop.cli.Main.startFOP(Main.java:186)
    at org.apache.fop.cli.Main.main(Main.java:217)
Caused by: javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: A table-cell is spanning more rows than available in its parent element.
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:502)
    at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:285)
    ... 3 more
Caused by: org.apache.fop.fo.ValidationException: A table-cell is spanning more rows than available in its parent element.
    at org.apache.fop.fo.flow.table.FixedColRowGroupBuilder.endTablePart(FixedColRowGroupBuilder.java:183)
    at org.apache.fop.fo.flow.table.VariableColRowGroupBuilder$6.play(VariableColRowGroupBuilder.java:107)
    at org.apache.fop.fo.flow.table.VariableColRowGroupBuilder.endTable(VariableColRowGroupBuilder.java:116)
    at org.apache.fop.fo.flow.table.Table.finalizeNode(Table.java:260)
    at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
    at org.apache.fop.fo.flow.table.Table.endOfNode(Table.java:243)
    at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
    at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
    at org.apache.xalan.transformer.TransformerIdentityImpl.endElement(TransformerIdentityImpl.java:1102)
    at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
    at org.apache.xerces.xinclude.XIncludeHandler.endElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:485)
    ... 4 more

---------

javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: A table-cell is spanning more rows than available in its parent element.
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:502)
    at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:285)
    at org.apache.fop.cli.InputHandler.renderTo(InputHandler.java:115)
    at org.apache.fop.cli.Main.startFOP(Main.java:186)
    at org.apache.fop.cli.Main.main(Main.java:217)
Caused by: org.apache.fop.fo.ValidationException: A table-cell is spanning more rows than available in its parent element.
    at org.apache.fop.fo.flow.table.FixedColRowGroupBuilder.endTablePart(FixedColRowGroupBuilder.java:183)
    at org.apache.fop.fo.flow.table.VariableColRowGroupBuilder$6.play(VariableColRowGroupBuilder.java:107)
    at org.apache.fop.fo.flow.table.VariableColRowGroupBuilder.endTable(VariableColRowGroupBuilder.java:116)
    at org.apache.fop.fo.flow.table.Table.finalizeNode(Table.java:260)
    at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
    at org.apache.fop.fo.flow.table.Table.endOfNode(Table.java:243)
    at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
    at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
    at org.apache.xalan.transformer.TransformerIdentityImpl.endElement(TransformerIdentityImpl.java:1102)
    at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
    at org.apache.xerces.xinclude.XIncludeHandler.endElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:485)
    ... 4 more
---------
org.apache.fop.fo.ValidationException: A table-cell is spanning more rows than available in its parent element.
    at org.apache.fop.fo.flow.table.FixedColRowGroupBuilder.endTablePart(FixedColRowGroupBuilder.java:183)
    at org.apache.fop.fo.flow.table.VariableColRowGroupBuilder$6.play(VariableColRowGroupBuilder.java:107)
    at org.apache.fop.fo.flow.table.VariableColRowGroupBuilder.endTable(VariableColRowGroupBuilder.java:116)
    at org.apache.fop.fo.flow.table.Table.finalizeNode(Table.java:260)
    at org.apache.fop.fo.FONode.endOfNode(FONode.java:330)
    at org.apache.fop.fo.flow.table.Table.endOfNode(Table.java:243)
    at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
    at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
    at org.apache.xalan.transformer.TransformerIdentityImpl.endElement(TransformerIdentityImpl.java:1102)
    at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
    at org.apache.xerces.xinclude.XIncludeHandler.endElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:485)
    at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:285)
    at org.apache.fop.cli.InputHandler.renderTo(InputHandler.java:115)
    at org.apache.fop.cli.Main.startFOP(Main.java:186)
    at org.apache.fop.cli.Main.main(Main.java:217)

【问题讨论】:

标签: xml xsd docbook relaxng docbook-5


【解决方案1】:

我建议使用 XSLT 来检查您在 XSL 文件中定义的约束。

我刚刚准备了一个用于检测您提到的特定问题的文件,您可以使用xsltproc check-tables.xsl article.xml 运行它

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns:db="http://docbook.org/ns/docbook"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- Author: Alberto González Palomo http://sentido-labs.com
       2016-12-24 00:20 -->

  <!-- BEGIN checks -->

  <xsl:template match="db:tbody">
    <xsl:variable name="row-count" select="count(db:tr)"/>
    <xsl:for-each select=".//db:td[@rowspan]">
      <xsl:variable name="last-row-spanned" select="count(parent::db:tr/preceding-sibling::db:tr) + @rowspan"/>
      <xsl:if test="$last-row-spanned &gt; $row-count">
        <xsl:call-template name="error">
          <!-- Optional in this case:
               <xsl:with-param name="location" select="."/>
          -->
          <xsl:with-param name="message">A table-cell is spanning more rows than available in its parent element.</xsl:with-param>
        </xsl:call-template>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

  <!-- END checks -->


  <xsl:output method="text"/>

  <xsl:template match="text()"><!-- Omit text content. --></xsl:template>

  <xsl:template name="error">
    <xsl:param name="location" select="."/>
    <xsl:param name="message">No error message available.</xsl:param>

    <!-- To stop at the first error, set the attribute terminate="yes".
         In xsltproc, this also causes the process to return a failure value.
         -->
    <xsl:message terminate="no">
      <xsl:text>Error: </xsl:text>
      <xsl:call-template name="xpath">
        <xsl:with-param name="location" select="$location"/>
      </xsl:call-template>
      <xsl:text>: </xsl:text>
      <xsl:value-of select="$message"/>
    </xsl:message>
  </xsl:template>

  <xsl:template name="xpath">
    <xsl:param name="location" select="."/>
    <xsl:for-each select="$location/parent::*">
      <xsl:call-template name="xpath"/>
    </xsl:for-each>

    <xsl:text>/</xsl:text>
    <xsl:variable name="element-name" select="name($location)"/>
    <xsl:value-of select="$element-name"/>

    <xsl:variable name="preceding" select="count($location/preceding-sibling::*[name() = $element-name])"/>
    <xsl:variable name="following" select="count($location/following-sibling::*[name() = $element-name])"/>
    <xsl:if test="$preceding + $following &gt; 0">
      <xsl:text>[</xsl:text>
      <xsl:value-of select="1 + $preceding"/>
      <xsl:text>]</xsl:text>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

"db:tbody" 的模板计算可用行数,然后遍历所有具有@rowspan 属性的td 元素,如果元素位置和@rowspan 的总和更大,则打印错误消息比tbody 中的tr 行数:

错误:/article/table/tbody/tr/td:表格单元跨越更多行 比在其父元素中可用。

您可以通过在"db:tbody" 模板中添加更多检查或为其他元素编写新模板来扩展它,您可以通过将模板拆分为单独的XSL 文件并使用&lt;xsl:import/&gt;&lt;xsl:include/&gt; 包含它们来模块化它.

我们当然可以用任何其他支持 XPath 的语言编写类似的程序,但您手头已经有了 XSLT 处理器。

【讨论】:

  • count(parent::db:tr/preceding-sibling::db:tr) 在我看来是错误的,因为您认为在这种情况下 @rowspan 将等于 1。
  • @malat 嗨,计数给出了有问题的行之前的行数,然后我们得到了 @rowspan 的值。因此,如果在这一行之前有 5 行,并且这一行的行跨度为 3,则跨越的最后一行的从 1 开始的索引将是 5+3=8
  • @malat 再次嗨,也许您的意思是该表达式假定当前行之前的所有行的行跨度为 1。这很好,因为根据 HTML 标准 [html],当前行上方的行跨度大于 1 的单元格不会将任何单元格向下推,而是向右推。 @rowspan 不会在任何地方添加行,否则 fop 不会抱怨,只会添加任何额外的行。 [html]w3.org/TR/html401/struct/tables.html#h-11.2.6.1
猜你喜欢
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
  • 2018-12-27
  • 1970-01-01
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多