2016-12-13 6 views
0

Мне не повезло, что у меня есть полный ответ в моем previous post. Поэтому я снова пытаюсь использовать другой подход.Обнаружение ошибки элемента таблицы в документе docbook 5.0

Как бы один обнаружить ошибку в следующем Docbook статье с 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 [*]


UPDATE: Я не ищу общего решения всех возможных проблем с FO, я просто ищу способ отслеживания i ssue (s) в длинном и сложном <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$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) 
+1

См. Ответ на http://stackoverflow.com/questions/18998498/validate-fo-file/19001319#19001319 и см. Https://www.oxygenxml.com/forum/topic7924.html#p24197: « проблема с XSL-FO заключается в том, что нет инструмента, который может полностью и правильно его проверять.XML-схема не может указывать все ограничения, которые находятся в выходном файле XSL-FO ... * Лучшая проверка для меня - это обработка XSL-FO в PDF и, таким образом, позволить процессору выдавать предупреждения и ошибки по мере их возникновения *. «Хотя я понимаю ограничение состоит в том, что FOP не дает строку + col ошибки в источнике. – sideshowbarker

+0

Ваша таблица образцов не является таблицей CALS, но вы ссылаетесь на http://tdg.docbook.org/tdg/5.0/cals.table.html. – mzjn

+0

Единственный инструмент, о котором я могу думать, это Schematron. Возможно, можно использовать правила Schematron для определения значений bad rows. – mzjn

ответ

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" подсчитывает количество строк доступно, то итерацию по всем элементам td которые имеют атрибут @rowspan и выводит сообщение об ошибке, если сумма позиции элемента и @rowspan больше, чем число строк tr в tbody:

Error: /article/table/tbody/tr/td : A table-cell is spanning more rows than available in its parent element.

Вы можете расширить его, добавив дополнительные проверки в шаблон "db:tbody" или путем написания новых шаблонов для других элементов, и вы можете его модулизовать, разделив шаблоны в отдельных файлах XSL и включив их в <xsl:import/> или <xsl:include/>.

Мы могли бы, конечно, написать аналогичную программу на любом другом языке с поддержкой XPath, но у вас уже есть XSLT-процессор под рукой.

+0

'count (parent :: db: tr/previous-sibling :: db: tr)' выглядит неправильно меня, так как вы предполагаете, что '@ rowspan' будет равным одному в этом случае. – malat

+0

@malat hi, подсчет дает количество строк перед тем, о котором идет речь, а затем мы имеем значение '@ rowspan'. Итак, если перед этим есть строки '5', и у этого есть столбец строк' 3', индекс на основе 1 последней строки, охватываемой, будет '5 + 3 = 8'. –

+0

@malat привет, может быть, что вы имеете в виду, так это выражение предполагает, что все строки перед текущим имеют длину строки в одном. Это прекрасно, потому что в соответствии со стандартом HTML [html] ячейка над текущей строкой с числом строк больше 1 не будет толкать любые ячейки вниз, а вправо. '@ rowspan' не добавляет строк нигде, иначе fop не будет жаловаться, а просто добавит лишние строки. [html] https://www.w3.org/TR/html401/struct/tables.html#h-11.2.6.1 –

Смежные вопросы