1 | <?xml version='1.0' encoding='UTF-8' ?> |
---|
2 | <!-- |
---|
3 | Normalize an XML document to make it easier to compare whether 2 documents will |
---|
4 | be seen as "equal" to an XML processor. |
---|
5 | |
---|
6 | The normalization is similar, in spirit, to {@link https://www.w3.org/TR/xml-c14n11/ Canonical XML}, |
---|
7 | but without some aspects of C14N that make the kinds of assertions we need difficult. |
---|
8 | |
---|
9 | For example, the following XML documents will be interpreted the same by an XML processor, |
---|
10 | even though a string comparison of them would show differences: |
---|
11 | |
---|
12 | <root xmlns='urn:example'> |
---|
13 | <ns0:child xmlns:ns0='urn:another-example'>this is a test</ns0:child> |
---|
14 | </root> |
---|
15 | |
---|
16 | <ns0:root xmlns:ns0='urn:example'> |
---|
17 | <child xmlns='urn:another-example'>this is a test</child> |
---|
18 | </ns0:root> |
---|
19 | --> |
---|
20 | <xsl:transform |
---|
21 | xmlns:xsl='http://www.w3.org/1999/XSL/Transform' |
---|
22 | version='1.0' |
---|
23 | > |
---|
24 | |
---|
25 | <!-- |
---|
26 | Output UTF-8 XML, no indentation and all CDATA sections replaced with their character content. |
---|
27 | --> |
---|
28 | <xsl:output |
---|
29 | method='xml' |
---|
30 | indent='no' |
---|
31 | cdata-section-elements='' |
---|
32 | encoding='UTF-8' /> |
---|
33 | |
---|
34 | <!-- |
---|
35 | Strip insignificant white space. |
---|
36 | --> |
---|
37 | <xsl:strip-space elements='*' /> |
---|
38 | |
---|
39 | <!-- |
---|
40 | Noramlize elements by not relying on the prefix used in the input document |
---|
41 | and ordering attributes first by namespace-uri and then by local-name. |
---|
42 | --> |
---|
43 | <xsl:template match='*' priority='10'> |
---|
44 | <xsl:element name='{local-name()}' namespace='{namespace-uri()}'> |
---|
45 | <xsl:apply-templates select='@*'> |
---|
46 | <xsl:sort select='namespace-uri()' /> |
---|
47 | <xsl:sort select='local-name()' /> |
---|
48 | </xsl:apply-templates> |
---|
49 | |
---|
50 | <xsl:apply-templates select='node()' /> |
---|
51 | </xsl:element> |
---|
52 | </xsl:template> |
---|
53 | |
---|
54 | <!-- |
---|
55 | Noramlize attributes by not relying on the prefix used in the input document. |
---|
56 | --> |
---|
57 | <xsl:template match='@*'> |
---|
58 | <xsl:attribute name='{local-name()}' namespace='{namespace-uri()}'> |
---|
59 | <xsl:value-of select='.' /> |
---|
60 | </xsl:attribute> |
---|
61 | </xsl:template> |
---|
62 | |
---|
63 | <!-- |
---|
64 | Strip comments. |
---|
65 | --> |
---|
66 | <xsl:template match='comment()' priority='10' /> |
---|
67 | |
---|
68 | <!-- |
---|
69 | Pass all other nodes through unchanged. |
---|
70 | --> |
---|
71 | <xsl:template match='node()'> |
---|
72 | <xsl:copy> |
---|
73 | <xsl:apply-templates select='node()' /> |
---|
74 | </xsl:copy> |
---|
75 | </xsl:template> |
---|
76 | </xsl:transform> |
---|