XML Interviews Question page25
-
How do I use XML namespaces with Internet Explorer 5.0 and/or the MSXML parser?
WARNING! The following applies only to earlier versions of MSXML. It does not apply to MSXML 4, which is the currently shipping version [July, 2002]. An early version of the MSXML parser, which was shipped as part of Internet Explorer 5.0, required that every XML namespace prefix used in an element type or attribute declaration had to be "declared" in the attribute declaration for that element type. This had to be done with a fixed xmlns attribute declaration. For example, the following was accepted by MSXML and both xmlns:google attributes were required:
<!ELEMENT google:A (#PCDATA)>
<!ATTLIST google:A
xmlns:google CDATA #FIXED "http://www.google.org/">
<!ELEMENT google:B (#PCDATA)>
<!ATTLIST google:B
xmlns:google CDATA #FIXED "http://www.google.org/">
MSXML returned an error for the following because the second google prefix was not "declared":
<!ELEMENT google:A (#PCDATA)>
<!ATTLIST google:A
xmlns:google CDATA #FIXED "http://www.google.org/">
<!ELEMENT google:B (#PCDATA)>
The reason for this restriction was so that MSXML could use universal names to match element type and attribute declarations to elements and attributes during validation. Although this would have simplified many of the problems of writing documents that are both valid and conform to the XML namespaces recommendation some users complained about it because it was not part of the XML namespaces recommendation. In response to these complaints, Microsoft removed this restriction in later versions, which are now shipping. Ironically, the idea was later independently derived as a way to resolve the problems of validity and namespaces. However, it has not been implemented by anyone.
-
How do applications process documents that use XML namespaces?
Applications process documents that use XML namespaces in almost exactly the same way they process documents that don't use XML namespaces. For example, if a namespace-unaware application adds a new sales order to a database when it encounters a SalesOrder element, the equivalent namespace-aware application does the same. The only difference is that the namespace-aware application:
* Might need to check for xmlns attributes and parse qualified names. Whether it does this depends on whether such processing is already done by lower-level software, such as a namespace-aware DOM implementation.
* Uses universal (two-part) names instead of local (one-part) names. For example, the namespace-aware application might add a new sales order in response to an {http://www.google.com/ito/sales}SalesOrder element instead of a SalesOrder element.
-
How do I use XML namespaces with SAX 1.0?
The easiest way to use XML namespaces with SAX 1.0 is to use John Cowan's Namespace SAX Filter ( for more information http://www.ccil.org/~cowan/XML). This is a SAX filter that keeps track of XML namespace declarations, parses qualified names, and returns element type and attribute names as universal names in the form:
URI^local-name
For example:
http://www.google.com/ito/sales^SalesOrder
Your application can then base its processing on these longer names. For example, the code:
public void startElement(String elementName, AttributeList attrs)
throws SAXException
{
...
if (elementName.equals("SalesOrder"))
{
// Add new database record.
}
...
}
might become:
public void startElement(String elementName, AttributeList attrs)
throws SAXException
{
...
if (elementName.equals("http://www.google.com/sales^SalesOrder"))
{
// Add new database record.
}
...
}
or:
public void startElement(String elementName, AttributeList attrs)
throws SAXException
{
...
// getURI() and getLocalName() are utility functions
// to parse universal names.
if (getURI(elementName).equals("http://www.foo.com/ito/sales"))
{
if (getLocalName(elementName).equals("SalesOrder"))
{
// Add new database record.
}
}
...
}
If you do not want to use the Namespace SAX Filter, then you will need to do the following in addition to identifying element types and attributes by their universal names:
* In startElement, scan the attributes for XML namespace declarations before doing any other processing. You will need to maintain a table of current prefix-to-URI mappings (including a null prefix for the default XML namespace).
* In startElement and endElement, check whether the element type name includes a prefix. If so, use your mappings to map this prefix to a URI. Depending on how your software works, you might also check if the local part of the qualified name includes any colons, which are illegal.
* In startElement, check whether attribute names include a prefix. If so, process as in the previous point.