Name

Dita::Validate - In situ validation of XML parse trees representing OASIS DITA documents.

Synopsis

Parse some XML representing a document that almost conforms to DITA:

use Data::Edit::Xml;
use Dita::Validate;

my $x = Data::Edit::Xml::new(<<END);
<ol>
<li><p>ppp</p></li>
<li><q>qqq</q></li>
<li><conbody>ccc</conbody></li>
</ol>
END

Validate the XML tree structure against the DITA standard and diagnose any errors in situ:

if (my $r = Dita::Validate::allChildren($x))
 {
  ok $r->last->tag eq q(li);
  ok $r->fail->tag eq q(conbody);
  ok $r->reason    eq q(Tag: conbody cannot appear first under tag: li);
  ok join(" ", @{$r->next}) =~ m(b boolean cite cmdname codeblock);
 }
 

This approach avoids the need to: construct a complete DITA topic, write the topic to a file, apply xmllint to the file containing the topic and then manually connect the resulting error messages back to the failing nodes in the parse tree.

This module does not require you to install DITA-OT or xmllint. To apply xmllint to a large number of files see: Data::Edit::Xml::Lint.

The deterministic finite state automatons used internally to validate the XML representing DITA conforming documents were obtained by parsing the Normative Form of the DITA specification with Data::Edit::Xml and then applying Data::NFA and Data::DFA.

Description

The following sections describe the methods in each functional area of this module. For an alphabetic listing of all methods by name see Index.

Validate

Validate the structure of an XML parse tree representing an OASIS DITA document without using the DITA-OT toolkit.

directChildren($)

Validate the children immediately under a parent node of an Data::Edit::Xml parse tree. Return undef if the child nodes occur are complete and in a valid order as defined by DITA else return a description of why the validation failed.

   Parameter  Description         
1  $parent    Node in parse tree  

Example:

my $x = Data::Edit::Xml::new(<<END);
<p>aaa<p>
</p>
</p>
END

my $r = Dita::Validate::directChildren($x);

ok $r->last->text eq qq(aaa);

ok $r->reason eq q(Tag: p cannot appear after tag: CDATA under tag: p);

This is a static method and so should be invoked as:

Dita::Validate::directChildren

allChildren($)

Validate all the child nodes in the entire sub tree of a parent node in an Data::Edit::Xml parse tree representing a DITA document. Return undef if they are complete and occur in a valid order else return a description of why the validation failed.

   Parameter  Description         
1  $parent    Node in parse tree  

Example:

my $x = Data::Edit::Xml::new(<<END);
<ol>
<li><p>ppp</p></li>
<li><q>qqq</q></li>
<li><conbody>ccc</conbody></li>
</ol>
END

if (my $r = Dita::Validate::allChildren($x)) {

ok $r->last->tag eq q(li);

ok $r->fail->tag eq q(conbody);

ok $r->reason    eq q(Tag: conbody cannot appear first under tag: li);

ok join(" ", @{$r->next}) =~ m(b boolean cite cmdname codeblock);

This is a static method and so should be invoked as:

Dita::Validate::allChildren

Validation results

If the validation of the XML Parse tree corresponding to the input DITA fails then this object is returned to describe the reason for the failure in detail:

fail :lvalue

The node in the XML parse tree at which validation failed.

last :lvalue

The last valid node visited in the XML parse tree before validation failed.

next :lvalue

The tags that would have succeeded at the last valid node.

reason :lvalue

A readable description of the error.

Private Methods

new()

Create a new set of Dita XML validation DFAs. Each Data::DFA below has been dumped, zipped, then converted to base 64 for convenient storage.

result($$$$)

Create a validation results description.

   Parameter     Description                      
1  $node         Last good node                   
2  $failingNode  Node at which validation failed  
3  $transitions  Array of possible symbols        
4  $reason       Readable reason for failure      

This is a static method and so should be invoked as:

Dita::Validate::result

Index

1 allChildren

2 directChildren

3 fail

4 last

5 new

6 next

7 reason

8 result

Installation

This module is written in 100% Pure Perl and, thus, it is easy to read, use, modify and install.

Standard Module::Build process for building and installing modules:

perl Build.PL
./Build
./Build test
./Build install

Author

philiprbrenan@gmail.com

http://www.appaapps.com

Copyright

Copyright (c) 2016-2018 Philip R Brenan.

This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.