Namespaces


JDOM's Namespace class, shown in Example 15.17, represents a namespace attached to an element or an attribute. Each namespace has a URI. If the namespace is not a default namespace, then it also has a prefix. Otherwise, the prefix is the empty string.

Example 15.17 The JDOM Namespace Class
 package org.jdom; public final class Namespace {   // Common namespaces   public static final Namespace NO_NAMESPACE;   public static final Namespace XML_NAMESPACE;   // Factory methods   public static Namespace getNamespace(String prefix, String uri);   public static Namespace getNamespace(String uri);   // Getter methods   public String getPrefix();   public String getURI();   // Utility methods   public boolean equals(Object o);   public String toString();   public int hashCode(); } 

Because repeating long strings such as "http://www.w3.org/2002/01/P3Pv1" on each element can eat up memory very quickly, and because a typical document contains many elements in the same namespace, this class uses the flyweight design pattern. This means that the constructors are private, and you'll need to use the factory methods to create Namespace objects. Alternately, the Element and Attribute classes allocate or reuse the necessary Namespace objects automatically when you pass string forms of the namespace URIs to their constructors or setNamespace() methods.

For example, I try to use well- formed HTML on most of my sites, but I generally don't attach the XHTML namespace (http://www.w3.org/1999/xhtml) where I should. The following method forces all unqualified elements into the XHTML namespace:

 public static void xhtmlQualify(Element element) {   Namespace xhtml    = Namespace.getNamespace("http://www.w3.org/1999/xhtml");   if (element.getNamespace() == Namespace.NO_NAMESPACE) {     element.setNamespace(xhtml);   }   List childElements = element.getChildren();   Iterator iterator = childElements.iterator();   while (iterator.hasNext()) {     Element child = (Element) iterator.next();     xhtmlQualify(child);   } } 

This changes the Document object in place (but not the original file on disk or on the network). It does not create any new node objects. You could use this as a filter before passing the Document object to a different method that expected pure XHTML. (In practice, you'd probably also need to change all of the element names to lowercase and add a DocType .)

In general, you don't need to worry about exactly where the xmlns and xmlns: prefix attributes that declare namespaces are placed. Indeed JDOM won't let you add attributes with these names because it stores them separately from the other attributes. When an outputter converts a JDOM Document to a DOM Document , a SAX event sequence, or a stream of bytes, it will figure out where it needs to put namespace declarations to make everything come out right. However, some XML applications, including SOAP, XSLT, and the W3C XML Schema Language, also use namespace prefixes in attribute values and even element content. These prefixes are not necessarily used on any element or attribute names in the document, but the prefixes still need to be declared. For example, the simple XSLT stylesheet in Example 15.18 needs to declare the prefix svg even though it's only used in the value of the match attribute.

Example 15.18 An XML Document That Uses Namespace Prefixes in Attribute Values
 <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   xmlns:svg="http://www.w3.org/2000/svg">   <xsl:template match="svg:rect">     <rectangle><xsl:apply-templates/></rectangle>   </xsl:template> </xsl:stylesheet> 

You can add these extra namespace bindings through the addNamespaceDeclaration() method in the Element class. If necessary, you can remove one with the removeNamespaceDeclaration() method:

 public Element  addNamespaceDeclaration  (Namespace  namespace  )  public Element  removeNamespaceDeclaration  (Namespace  namespace  ) 

For example, the following code fragment creates the xsl:stylesheet element in Example 15.18 and adds the SVG namespace declaration to it:

 Element stylesheet = new Element(      "stylesheet", "xsl", "http://www.w3.org/1999/XSL/Transform"); Namespace svg = Namespace.getNamespace("svg",                                    "http://www.w3.org/2000/svg"); stylesheet.addNamespaceDeclaration(svg); 

If you encounter a namespace prefix in character data, and you need to know what prefix it maps to, then you have to check the parent element's namespace, all of its attributes' namespaces, and all of its additional namespaces. If that doesn't give you an answer, repeat the process for the next nearest ancestor , and continue until you either find the answer or run out of ancestors . This can be a little involved, but fortunately the Element class provides a simple method that tells you what URI any given prefix maps to within its scope:

 public Namespace  getNamespace  (String  prefix  ) 

Since prefixes can be remapped to different URIs in descendant elements, always check the namespace in scope from the Attribute or Text object's immediate parent.



Processing XML with Java. A Guide to SAX, DOM, JDOM, JAXP, and TrAX
Processing XML with Javaв„ў: A Guide to SAX, DOM, JDOM, JAXP, and TrAX
ISBN: 0201771861
EAN: 2147483647
Year: 2001
Pages: 191

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net