<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to Serializing XML</title><link>https://sourceforge.net/p/pretty-markup/wiki/Serializing%2520XML/</link><description>Recent changes to Serializing XML</description><atom:link href="https://sourceforge.net/p/pretty-markup/wiki/Serializing%20XML/feed" rel="self"/><language>en</language><lastBuildDate>Mon, 14 May 2012 15:35:46 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/pretty-markup/wiki/Serializing%20XML/feed" rel="self" type="application/rss+xml"/><item><title>WikiPage Serializing XML modified by OmniMark Code</title><link>https://sourceforge.net/p/pretty-markup/wiki/Serializing%2520XML/</link><description>&lt;pre&gt;--- v1 
+++ v2 
@@ -5,104 +5,103 @@
 
 First, we need to escape all the meta-characters present in the content, and `translate` rules are perfect for  the purpose: 
 
-&lt;pre&gt;
-translate "&amp;"
-   output "&amp;amp;"
-
-translate "&lt;"
-   output "&amp;lt;"
-&lt;/pre&gt;
-
+&lt;div class="codehilite"&gt;&lt;pre&gt;
+&lt;span class="kr"&gt;translate&lt;/span&gt; &lt;span class="s"&gt;"&amp;amp;"&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"&amp;amp;amp;"&lt;/span&gt;
+&amp;nbsp;
+&lt;span class="kr"&gt;translate&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;"&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"&amp;amp;lt;"&lt;/span&gt;
+&lt;/pre&gt;&lt;/div&gt;
+
 Some people prefer to escape the greater-than characters as well, for symmetry, but we'll keep our serializer  minimal. To escape non-ASCII characters in the input, we need another `translate` rule. We shall assume the input  is UTF-8 encoded, so we need to import the `omutf8` library module: 
 
-&lt;pre&gt;
-include "utf8pat.xin"
-
-translate (lookahead [any \\ "%10#%13#" | "%32#" to "%127#"]) (utf8-char =&gt; c)
-   output "&amp;" || "d" % utf8-char-number c || ";"
-&lt;/pre&gt;
+&lt;div class="codehilite"&gt;&lt;pre&gt;
+&lt;span class="kr"&gt;include&lt;/span&gt; &lt;span class="s"&gt;"utf8pat.xin"&lt;/span&gt;
+&amp;nbsp;
+&lt;span class="kr"&gt;translate&lt;/span&gt; (&lt;span class="kr"&gt;lookahead&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt; &lt;span class="s"&gt;"%10#%13#"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s"&gt;"%32#"&lt;/span&gt; &lt;span class="kr"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"%127#"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;) (utf8-char &lt;span class="o"&gt;=&gt;&lt;/span&gt; c)
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"&amp;amp;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s"&gt;"d"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; utf8-char-number c &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s"&gt;";"&lt;/span&gt;
+&lt;/pre&gt;&lt;/div&gt;
 
 The `translate` rules above can handle both the element content and the attribute values, because they largely  require the same treatment. The following rule, however, is better invoked for attribute values only, because the  quotes and newlines in the content look much better when they're left unescaped. Inside an attribute, on the other  hand, an unescaped quote character would cause a markup error, while a tab or a newline character would be  indistinguishable from a space character. 
 
-&lt;pre&gt;
-group "translate attributes"
-translate '"'
-   output "&amp;quot;"
-
-translate ["%9#%10#%13#"] =&gt; whitespace-char
-   output "&amp;#x" || "16rd" % binary whitespace-char || ";"
-
-group #implied
-&lt;/pre&gt;
+&lt;div class="codehilite"&gt;&lt;pre&gt;
+&lt;span class="kr"&gt;group&lt;/span&gt; &lt;span class="s"&gt;"translate attributes"&lt;/span&gt;
+&lt;span class="kr"&gt;translate&lt;/span&gt; &lt;span class="s"&gt;'"'&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"&amp;amp;quot;"&lt;/span&gt;
+&amp;nbsp;
+&lt;span class="kr"&gt;translate&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"%9#%10#%13#"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&gt;&lt;/span&gt; whitespace-char
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"&amp;amp;#x"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s"&gt;"16rd"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="kr"&gt;binary&lt;/span&gt; whitespace-char &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s"&gt;";"&lt;/span&gt;
+&amp;nbsp;
+&lt;span class="kr"&gt;group&lt;/span&gt; &lt;span class="nb"&gt;#implied&lt;/span&gt;
+&lt;/pre&gt;&lt;/div&gt;
 
 In order to actually activate these `translate` rules on attribute values, we must replace the `attribute a`  expression in our `element` rule by `"%v(a)"` and select the proper group. And we can take care of the empty  elements at the same time: 
 
-&lt;pre&gt;
-element #implied
-   output "&lt;%q"
-   using group "translate attributes"
-   repeat over specified attributes as a
-      output " " || key of attribute a || '="%v(a)"'
-   again
-   output content is empty-tag -&gt; "/&gt;%c" | "&gt;%c&lt;/%q&gt;"
-&lt;/pre&gt;
+&lt;div class="codehilite"&gt;&lt;pre&gt;
+&lt;span class="kr"&gt;element&lt;/span&gt; &lt;span class="nb"&gt;#implied&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;%q"&lt;/span&gt;
+   &lt;span class="kr"&gt;using&lt;/span&gt; &lt;span class="kr"&gt;group&lt;/span&gt; &lt;span class="s"&gt;"translate attributes"&lt;/span&gt;
+   &lt;span class="kr"&gt;repeat&lt;/span&gt; &lt;span class="kr"&gt;over&lt;/span&gt; &lt;span class="kr"&gt;specified&lt;/span&gt; &lt;span class="kr"&gt;attributes&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; a
+      &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kr"&gt;key&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt; &lt;span class="kr"&gt;attribute&lt;/span&gt; a &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s"&gt;'="%v(a)"'&lt;/span&gt;
+   &lt;span class="kr"&gt;again&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="kr"&gt;content&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt; &lt;span class="kr"&gt;empty-tag&lt;/span&gt; &lt;span class="o"&gt;-&gt;&lt;/span&gt; &lt;span class="s"&gt;"/&gt;%c"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s"&gt;"&gt;%c&amp;lt;/%q&gt;"&lt;/span&gt;
+&lt;/pre&gt;&lt;/div&gt;
 
 Elements and textual content are not the only things we need to handle. If there are any external entity  references in the input, they must be processed. External data entities are easier to handle; the following rule  simply reproduces the original entity reference: 
 
-&lt;pre&gt;
-external-data-entity #implied
-   output "&amp;%q;"
-&lt;/pre&gt;
+&lt;div class="codehilite"&gt;&lt;pre&gt;
+&lt;span class="kr"&gt;external-data-entity&lt;/span&gt; &lt;span class="nb"&gt;#implied&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"&amp;amp;%q;"&lt;/span&gt;
+&lt;/pre&gt;&lt;/div&gt;
 
 Let us now look into external text entities. In absence of any user-defined rule, OmniMark would attempt to  expand the entity value and we'd get a monolithic XML document as the result. We may instead want to reproduce the  top-level document with unexpanded entity references. In that case, we cannot simply output a reference to the  same entity, because the output of an `external-text-entity` rule is fed back to the parser. The effect would be a  self-referential loop, which the parser would detect and report as a markup error. To prevent this, we must  redirect the output to the same stream where the parser output is going. If that stream is `#main-output`, for example, the rule would be: 
 
-&lt;pre&gt;
-external-text-entity #implied when entity is general
-   put #main-output "&amp;%q;"
-&lt;/pre&gt;
+&lt;div class="codehilite"&gt;&lt;pre&gt;
+&lt;span class="kr"&gt;external-text-entity&lt;/span&gt; &lt;span class="nb"&gt;#implied&lt;/span&gt; &lt;span class="kr"&gt;when&lt;/span&gt; &lt;span class="kr"&gt;entity&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt; &lt;span class="kr"&gt;general&lt;/span&gt;
+   &lt;span class="kr"&gt;put&lt;/span&gt; &lt;span class="nb"&gt;#main-output&lt;/span&gt; &lt;span class="s"&gt;"&amp;amp;%q;"&lt;/span&gt;
+&lt;/pre&gt;&lt;/div&gt;
 
 Our markup is now guaranteed to be well-formed. We can stop at this point, and we'll have a perfectly good XML  *normalizer*: the output won't be quite the same as the input, but to most applications out there that don't care  for comments and processsing instructions it will look exactly the same. The rest is optional, and depends on what  kind of output is needed.  
 
 If any `CDATA` marked sections were present in the input, our normalizer would convert them to normal content  with individual characters escaped. If we want to preserve the marked sections, we need the following rule: 
 
-&lt;pre&gt;
-marked-section cdata
-   output "&lt;![CDATA["
-   repeat scan "%zc"
-   match any ++ =&gt; rest lookahead ("]]&gt;" | value-end)
-      output rest
-   match "]]&gt;"
-      not-reached message "A CDATA marked section cannot contain the string ']]&gt;'"
-   again
-   output "]]&gt;"
-&lt;/pre&gt;
+&lt;div class="codehilite"&gt;&lt;pre&gt;
+&lt;span class="kr"&gt;marked-section&lt;/span&gt; &lt;span class="kr"&gt;cdata&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;![CDATA["&lt;/span&gt;
+   &lt;span class="kr"&gt;repeat&lt;/span&gt; &lt;span class="kr"&gt;scan&lt;/span&gt; &lt;span class="s"&gt;"%zc"&lt;/span&gt;
+   &lt;span class="kr"&gt;match&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;=&gt;&lt;/span&gt; rest &lt;span class="kr"&gt;lookahead&lt;/span&gt; (&lt;span class="s"&gt;"]]&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;value-end&lt;/span&gt;)
+      &lt;span class="kr"&gt;output&lt;/span&gt; rest
+   &lt;span class="kr"&gt;match&lt;/span&gt; &lt;span class="s"&gt;"]]&gt;"&lt;/span&gt;
+      &lt;span class="kr"&gt;not-reached&lt;/span&gt; &lt;span class="kr"&gt;message&lt;/span&gt; &lt;span class="s"&gt;"A CDATA marked section cannot contain the string ']]&gt;'"&lt;/span&gt;
+   &lt;span class="kr"&gt;again&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"]]&gt;"&lt;/span&gt;
+&lt;/pre&gt;&lt;/div&gt;
 
 The rule uses `%zc` instead of `%c` because the latter would run the `translate` rules on the content of the  marked section, which is not what we want.  
 
 Finally, we need a few more rules if we want to reproduce all the comments and processing instruction exactly  the way they were in the input XML document: 
 
-&lt;pre&gt;
-markup-comment
-   output "&lt;!--"
-   repeat scan "%zc"
-   match [any \\ "-"]+ =&gt; rest
-      output rest
-   match "-" lookahead ("-" | value-end)
-      not-reached message "An XML comment cannot contain the string '--'"
-   match "-"
-      output "-"
-   again
-   output "--&gt;"
-   output "%n"
-      when number of current elements = 0
-
-processing-instruction any\* =&gt; pi
-   output "&lt;?%g(pi)?&gt;"
-   output "%n"
-      when number of current elements = 0
-&lt;/pre&gt;
+&lt;div class="codehilite"&gt;&lt;pre&gt;
+&lt;span class="kr"&gt;markup-comment&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;!--"&lt;/span&gt;
+   &lt;span class="kr"&gt;repeat&lt;/span&gt; &lt;span class="kr"&gt;scan&lt;/span&gt; &lt;span class="s"&gt;"%zc"&lt;/span&gt;
+   &lt;span class="kr"&gt;match&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt; &lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;=&gt;&lt;/span&gt; rest
+      &lt;span class="kr"&gt;output&lt;/span&gt; rest
+   &lt;span class="kr"&gt;match&lt;/span&gt; &lt;span class="s"&gt;"-"&lt;/span&gt; &lt;span class="kr"&gt;lookahead&lt;/span&gt; (&lt;span class="s"&gt;"-"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;value-end&lt;/span&gt;)
+      &lt;span class="kr"&gt;not-reached&lt;/span&gt; &lt;span class="kr"&gt;message&lt;/span&gt; &lt;span class="s"&gt;"An XML comment cannot contain the string '--'"&lt;/span&gt;
+   &lt;span class="kr"&gt;match&lt;/span&gt; &lt;span class="s"&gt;"-"&lt;/span&gt;
+      &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"-"&lt;/span&gt;
+   &lt;span class="kr"&gt;again&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"--&gt;"&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"%n"&lt;/span&gt;
+      &lt;span class="kr"&gt;when&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt; &lt;span class="kr"&gt;current&lt;/span&gt; &lt;span class="kr"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
+&amp;nbsp;
+&lt;span class="kr"&gt;processing-instruction&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;=&gt;&lt;/span&gt; pi
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;?%g(pi)?&gt;"&lt;/span&gt;
+   &lt;span class="kr"&gt;output&lt;/span&gt; &lt;span class="s"&gt;"%n"&lt;/span&gt;
+      &lt;span class="kr"&gt;when&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt; &lt;span class="kr"&gt;current&lt;/span&gt; &lt;span class="kr"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0
+&lt;/pre&gt;&lt;/div&gt;
 
 All the rules above still can't reproduce the input XML document *exactly*. There are some things that the XML  parser simply cannot pass to the application. For example, we assume that there is only a single space before each  attribute, but in fact there could have been any amount of whitespace there. We also cannot tell if single or  double quotes were used for attribute values. Finally, the internal entity references are silently replaced by the  XML parser and we have no way of reproducing them.  
 
 One thing that we can guarantee is that the XML serialization process is *idempotent*: if we re-parse and  re-serialize the serialized XML output, we'll get the same result. 
-
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">OmniMark Code</dc:creator><pubDate>Mon, 14 May 2012 15:35:46 -0000</pubDate><guid>https://sourceforge.netf6b8779245880eea9b2e3fd517d152b8a04c6cc6</guid></item><item><title>WikiPage Serializing XML modified by OmniMark Code</title><link>https://sourceforge.net/p/pretty-markup/wiki/Serializing%2520XML/</link><description>Serializing XML 
================

As even the birds know by now, XML is much simpler than (and therefore obviously superior to) SGML. All the  things we need to take care of have already been listed in the introduction. Let's handle them one by one.  

First, we need to escape all the meta-characters present in the content, and `translate` rules are perfect for  the purpose: 

&lt;pre&gt;
translate "&amp;"
   output "&amp;amp;"

translate "&lt;"
   output "&amp;lt;"
&lt;/pre&gt;

Some people prefer to escape the greater-than characters as well, for symmetry, but we'll keep our serializer  minimal. To escape non-ASCII characters in the input, we need another `translate` rule. We shall assume the input  is UTF-8 encoded, so we need to import the `omutf8` library module: 

&lt;pre&gt;
include "utf8pat.xin"

translate (lookahead [any \\ "%10#%13#" | "%32#" to "%127#"]) (utf8-char =&gt; c)
   output "&amp;" || "d" % utf8-char-number c || ";"
&lt;/pre&gt;

The `translate` rules above can handle both the element content and the attribute values, because they largely  require the same treatment. The following rule, however, is better invoked for attribute values only, because the  quotes and newlines in the content look much better when they're left unescaped. Inside an attribute, on the other  hand, an unescaped quote character would cause a markup error, while a tab or a newline character would be  indistinguishable from a space character. 

&lt;pre&gt;
group "translate attributes"
translate '"'
   output "&amp;quot;"

translate ["%9#%10#%13#"] =&gt; whitespace-char
   output "&amp;#x" || "16rd" % binary whitespace-char || ";"

group #implied
&lt;/pre&gt;

In order to actually activate these `translate` rules on attribute values, we must replace the `attribute a`  expression in our `element` rule by `"%v(a)"` and select the proper group. And we can take care of the empty  elements at the same time: 

&lt;pre&gt;
element #implied
   output "&lt;%q"
   using group "translate attributes"
   repeat over specified attributes as a
      output " " || key of attribute a || '="%v(a)"'
   again
   output content is empty-tag -&gt; "/&gt;%c" | "&gt;%c&lt;/%q&gt;"
&lt;/pre&gt;

Elements and textual content are not the only things we need to handle. If there are any external entity  references in the input, they must be processed. External data entities are easier to handle; the following rule  simply reproduces the original entity reference: 

&lt;pre&gt;
external-data-entity #implied
   output "&amp;%q;"
&lt;/pre&gt;

Let us now look into external text entities. In absence of any user-defined rule, OmniMark would attempt to  expand the entity value and we'd get a monolithic XML document as the result. We may instead want to reproduce the  top-level document with unexpanded entity references. In that case, we cannot simply output a reference to the  same entity, because the output of an `external-text-entity` rule is fed back to the parser. The effect would be a  self-referential loop, which the parser would detect and report as a markup error. To prevent this, we must  redirect the output to the same stream where the parser output is going. If that stream is `#main-output`, for example, the rule would be: 

&lt;pre&gt;
external-text-entity #implied when entity is general
   put #main-output "&amp;%q;"
&lt;/pre&gt;

Our markup is now guaranteed to be well-formed. We can stop at this point, and we'll have a perfectly good XML  *normalizer*: the output won't be quite the same as the input, but to most applications out there that don't care  for comments and processsing instructions it will look exactly the same. The rest is optional, and depends on what  kind of output is needed.  

If any `CDATA` marked sections were present in the input, our normalizer would convert them to normal content  with individual characters escaped. If we want to preserve the marked sections, we need the following rule: 

&lt;pre&gt;
marked-section cdata
   output "&lt;![CDATA["
   repeat scan "%zc"
   match any ++ =&gt; rest lookahead ("]]&gt;" | value-end)
      output rest
   match "]]&gt;"
      not-reached message "A CDATA marked section cannot contain the string ']]&gt;'"
   again
   output "]]&gt;"
&lt;/pre&gt;

The rule uses `%zc` instead of `%c` because the latter would run the `translate` rules on the content of the  marked section, which is not what we want.  

Finally, we need a few more rules if we want to reproduce all the comments and processing instruction exactly  the way they were in the input XML document: 

&lt;pre&gt;
markup-comment
   output "&lt;!--"
   repeat scan "%zc"
   match [any \\ "-"]+ =&gt; rest
      output rest
   match "-" lookahead ("-" | value-end)
      not-reached message "An XML comment cannot contain the string '--'"
   match "-"
      output "-"
   again
   output "--&gt;"
   output "%n"
      when number of current elements = 0

processing-instruction any\* =&gt; pi
   output "&lt;?%g(pi)?&gt;"
   output "%n"
      when number of current elements = 0
&lt;/pre&gt;

All the rules above still can't reproduce the input XML document *exactly*. There are some things that the XML  parser simply cannot pass to the application. For example, we assume that there is only a single space before each  attribute, but in fact there could have been any amount of whitespace there. We also cannot tell if single or  double quotes were used for attribute values. Finally, the internal entity references are silently replaced by the  XML parser and we have no way of reproducing them.  

One thing that we can guarantee is that the XML serialization process is *idempotent*: if we re-parse and  re-serialize the serialized XML output, we'll get the same result. 

</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">OmniMark Code</dc:creator><pubDate>Fri, 11 May 2012 18:32:29 -0000</pubDate><guid>https://sourceforge.netf12ea2bfa1f21e4e07344a52e7631b00bdd6a531</guid></item></channel></rss>