Effective XML

Software Development 2004 West

Elliotte Rusty Harold

http://www.cafeconleche.org/

Part I: Syntax

Include an XML declaration

Optional, but you should treat it as required

Specifies version, character set, and encoding

Very important for detecting encoding

Helps identify XML documents in environments where file and media type information is unavailable or unreliable

Stay with XML 1.0

XML 1.1 adds:

Other languages: Yi, Mongolian, Burmese, Amharic

C0 control characters can be included with numeric character references

C1 control characters must use numeric character references

NEL is allowed as white space

Undeclaration of namespace prefixes

Incompatible with most XML parsers

Part II: Structure

The XML Stack

Allow All XML syntax

CDATA sections

Entity references

Processing instructions

Comments

Numeric character references

Document type declarations

These are all just different ways of representing the same core content; not different information

Distinguish text from markup

<programlisting><![CDATA[<value>
<double>28657</double>
</value>]]></programlisting>

The content is:
<value>
<double>28657</double>
</value>

This is the same:
<programlisting>&lt;value&gt;
&lt;double&gt;28657&lt;/double&gt;
&lt;/value&gt;</programlisting>

The reverse problem.

Using a tool to create XML from strings

A tree-based editor like <Oxygen/> or XML Spy

A WYSIWYG application like OpenOffice Writer or Apple's Keynote that saves its data into XML

A programming API such as DOM, JDOM, or XOM

The tool automatically escapes any reserved characters like <, >, or &. You do not do this.

Just because something looks like an XML tag does not always mean it is an XML tag. Context matters.

White space matters

Parsers report all white space in element content, including boundary white space

An xml:space attribute is for the client application only, not the parser

White space in attribute values is normalized

Parsers do not report white space in the prolog, epilog, the document type declaration, and tags.

Make structure explicit` through markup

Store metadata in attributes

Remember mixed content

Prefer URLs to unparsed entities and notations

Part III: Semantics

Use processing instructions for process-specific content

Intended only for a very particular process, often a purely local one

Describes how a particular process acts on the data in the document

Does not describe or add to the content itself

Instruction is a unit that can be treated in isolation.

Does not extend across a part of the XML document.

Data does not need to be validated.

Content is simple, and not XML-like.

Applies to the entire document

Processing instructions are not appropriate when:

Content is closely related to the content of the document itself.

Structure that extends beyond a single processing instruction.

Include all information in instance documents

Encode binary data using quoted printable and/or Base64

Use namespaces for modularity and extensibility

Rely on namespace URIs, not prefixes

Don't use namespace prefixes in element content and attribute values

Reuse XHTML for generic narrative content

Choose the right schema language for the job

DTDs

The W3C XML Schema Language

RELAX NG

Schematron

Pretend there's no such thing as the PSVI

Version documents, schemas, and stylesheets

Markup according to meaning

Use only what you need

Always use a parser

Layer Functionality

Program to standard APIs

Choose SAX for computer efficiency

Choose DOM for standards support

Read the complete DTD

Navigate with XPath

Serialize XML with XML

Validate inside your program with schemas

Part IV:Implementation

Write documents in Unicode

Parameterize XSLT style sheets

Avoid Vendor Lockin; Beware

Opaque, binary data used in place of marked up text.

Over-abbreviated, unclear element and attribute names like F17354 and grgyt

APIs that try to shield you from the raw XML

Products that focus on the "Infoset" to the exclusion of real XML

Alternate serializations of XML

Hang on to your relational database

Document Namespaces with RDDL

Preprocess XSLT on the server side

Implementation

Serve XML+CSS to the client

Supported by

Safari

IE 5.0 and later

Mozilla

Netscape 6 and later

Konqueror

Opera

Pick the correct MIME media type

application/xml

Not text/xml

Don't use charset parameter

application/mathml+xml

image/svg+xml

application/xslt+xml

Tidy Up Your HTML

Catalog common resources

Verify documents with XML digital signatures

Hide confidential data with XML encryption

Compress if space is a problem

//output

OutputStream fout = new FileOutputStream("data.xml.gz");

OutputStream out = new GZipOutputStream(fout);

OutputFormat format = new OutputFormat(document);

XMLSerializer output = new XMLSerializer(out, format);

output.serialize(doc);

// input

InputStream fin = new FileInputStream("data.xml.gz");

InputStream in = new GZipInputStream(fin);

DocumentBuilderFactory factory

= DocumentBuilderFactory.newInstance();

DocumentBuilder parser = factory.newDocumentBuilder();

Document doc = parser.parse(in); S

// work with the document...

To Learn More

This Presentation: http://cafeconleche.org/slides/sd2004west/effectivexml

Effective XML: 50 Specific Ways to Improve Your XML Documents

Elliotte Rusty Harold

Addison-Wesley, 2003

ISBN 0-321-15040-6

$44.99

http://cafeconleche.org/books/effectivexml

All legal text characters that can appear anywhere in an XML document can appear in #PCDATA. This includes characters like < and & that may have to be escaped with character or entity references. When an API presents the content of a node containing such a character to your code, it will give you the actual character, not the escaping text. Similarly, when you create such a node, the string you use should contain the actual character, not the entity or character reference.

Consider this DocBook programlisting element. A CDATA section is used to embed a literal sequence of XML text:

<programlisting><![CDATA[<value>

<double>28657</double>

</value>]]></programlisting>

Everything inside the CDATA section is content, not markup. The content of this programlisting element is this text:

<value>

<double>28657</double>

</value>

A CDATA section is not required for this trick to work either. For instance, consider this variation of the above element:

<programlisting>&lt;value&gt;

&lt;double&gt;28657&lt;/double&gt;

&lt;/value&gt;</programlisting>

The content of this element is exactly the same:

<value>

<double>28657</double>

</value>

In this case the markup of the entity references &lt; and &gt; is resolved to produce the text < and >. However, that's just syntax sugar. It does not affect the content in any way.

Now consider the reverse problem. Suppose you're creating an XML document in something at least a little more XML-aware than a text editor. Possibilities include:

A tree-based editor like <Oxygen/> or XML Spy

A WYSIWYG application like OpenOffice Writer or Apple's Keynote that saves its data into XML

A programming API such as DOM, JDOM, or XOM

In all cases, the creating tool will provide separate means to insert markup and text. The tool is responsible for escaping any reserved characters like <, >, or & when it saves the document. You do not need to do this. Indeed if you try by passing something like &lt;double&gt;28657&lt;/double&gt; into a method that expects to get plain text what it will actually save is something like &amp;lt;double&amp;gt;28657&amp;lt;/double&amp;gt;.

Similarly, you cannot type <double>28657</double> into a user interface widget that creates text and expect it to create an element. Instead what you will get in the serialized document is something like &lt;double&gt;28657&lt;/double&gt;. Instead, you should use the UI widget or method call designed for creating a new element.

The key thing to remember is this: just because something looks like an XML tag does not always mean it is an XML tag. Context matters. XML documents are made of markup that sometimes surrounds PCDATA, but that's the limit of the nesting. You can put PCDATA inside markup, and you can put markup inside markup, but you can't put markup inside PCDATA. CDATA sections are just an alternative means of escaping text. They are not a way to embed markup inside PCDATA.

2004-01-09T12:01:26