@@ -34,6 +34,14 @@ XML::Invisible - transform "invisible XML" documents into XML using a grammar
34
34
'print ast2xml(make_parser(join "", <>)->("(a+b)"))->toStringC14N(1)' \
35
35
examples/arith-grammar.ixml | xml_pp
36
36
37
+ # canonicalise a document
38
+ use XML::Invisible qw(make_parser make_canonicaliser);
39
+ my $ixml_grammar = from_file('examples/arith-grammar.ixml');
40
+ my $transformer = make_parser($ixml_grammar);
41
+ my $ast = $transformer->(from_file($ixml_input));
42
+ my $canonicaliser = make_canonicaliser($ixml_grammar);
43
+ my $canonical = $canonicaliser->($ast);
44
+
37
45
# DESCRIPTION
38
46
39
47
An implementation of Steven Pemberton's Invisible XML concept, using
@@ -111,6 +119,33 @@ Arguments:
111
119
112
120
- an AST from [ XML::Invisible::Receiver] ( https://metacpan.org/pod/XML::Invisible::Receiver )
113
121
122
+ ## make\_ canonicaliser
123
+
124
+ Exportable. Returns a function that when called with an AST as produced
125
+ from a document by a [ "make\_ parser"] ( #make_parser ) , returns a canonical version of
126
+ the original document, or ` undef ` if it failed.
127
+
128
+ Arguments:
129
+
130
+ - an XML::Invisible grammar
131
+
132
+ It uses a few heuristics:
133
+
134
+ - literals that are 0-1 (` ? ` ) or any number (` * ` ) will be omitted
135
+ - literals that are at least one (` + ` ) will be inserted once
136
+ - if an "any" group is given, the first one that matches will be selected
137
+
138
+ This last one means that if you want a canonical representation that is
139
+ not the bare minimum, provide that as a literal first choice (see the
140
+ ` assign ` rule below - while it will accept any or no whitespace, the
141
+ "canonical" version is given):
142
+
143
+ expr: target .assign source
144
+ target: +name
145
+ assign: ' = ' | (- EQUAL -)
146
+ source: -name
147
+ name: /( ALPHA (: ALPHA | DIGIT )* )/
148
+
114
149
# DEBUGGING
115
150
116
151
To debug, set environment variable ` XML_INVISIBLE_DEBUG ` to a true value.
0 commit comments