检测 docbook 5.0 文档中的 table 元素错误
Detecting table element error in docbook 5.0 document
我的 previous post 中没有完整的答案。所以我再次尝试使用不同的方法。
如何使用 table 检测以下 docbook 文章中的错误:
$ 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 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 问题的通用解决方案,我只是在寻找一种方法来跟踪长而复杂的 <table>
元素中的问题。
[*]
$ 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.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.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.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)
我建议使用 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 > $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 > 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
行数
Error: /article/table/tbody/tr/td
: A table-cell is spanning more rows
than available in its parent element.
您可以通过在 "db:tbody"
模板中添加更多检查或为其他元素编写新模板来扩展它,您可以通过将模板拆分为单独的 XSL 文件并将它们包含在 [=20] 中来对其进行模块化=] 或 <xsl:include/>
.
我们当然可以用任何其他支持 XPath 的语言编写类似的程序,但您手边已经有一个 XSLT 处理器。
我的 previous post 中没有完整的答案。所以我再次尝试使用不同的方法。
如何使用 table 检测以下 docbook 文章中的错误:
$ 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 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 问题的通用解决方案,我只是在寻找一种方法来跟踪长而复杂的 <table>
元素中的问题。
[*]
$ 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.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.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.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)
我建议使用 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 > $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 > 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
行数
Error:
/article/table/tbody/tr/td
: A table-cell is spanning more rows than available in its parent element.
您可以通过在 "db:tbody"
模板中添加更多检查或为其他元素编写新模板来扩展它,您可以通过将模板拆分为单独的 XSL 文件并将它们包含在 [=20] 中来对其进行模块化=] 或 <xsl:include/>
.
我们当然可以用任何其他支持 XPath 的语言编写类似的程序,但您手边已经有一个 XSLT 处理器。