[jdom-interest] exception with xml:lang

Jason Hunter jhunter at collab.net
Thu Aug 17 16:59:52 PDT 2000


Stacie,

Can you try your app again with the latest CVS tree?  (If you're using
the daily snapshots, wait til they're taken again.)  I just checked in
some code that I think will allow this to work.  

Basically I had the Namespace class implicitly recognize the "xml"
prefix as the namespace URI "http://www.w3.org/XML/1998/namespace" as
the spec indicates is correct behavior:

---
The namespace prefix, unless it is xml or xmlns, must have been declared
in a namespace declaration attribute in either the start-tag of the
element where the prefix is used or in an an ancestor element (i.e. an
element in whose content the prefixed markup occurs). The prefix xml is
by definition bound to the namespace name
http://www.w3.org/XML/1998/namespace. The prefix xmlns is used only for
namespace bindings and is not itself bound to any namespace name. 
---

-jh-

Stacie Clark wrote:
> 
> Ok.  This is the offending line:
> <label href="xpointer(//item[@type='gpsi:computation.netIncome'])"
> xml:lang="en">Net income</label>
> This is the stack:
> 
> Breakpoint hit: org.jdom.Verifier.checkNamespacePrefix (Verifier:190)
> main[1] locals
> Method arguments:
> Local variables:
>   prefix = xml
>   first = x
> main[1] where
>   [1] org.jdom.Verifier.checkNamespacePrefix (Verifier:190)
>   [2] org.jdom.Namespace.getNamespace (Namespace:124)
>   [3] org.jdom.Attribute.<init> (Attribute:120)
>   [4] org.jdom.input.SAXHandler.startElement (SAXHandler:616)
>   [5] org.apache.xerces.parsers.SAXParser.startElement (SAXParser:1371)
>   [6] org.apache.xerces.validators.common.XMLValidator.callStartElement (XMLVali
> dator:705)
>   [7] org.apache.xerces.framework.XMLDocumentScanner.scanElement (XMLDocumentSca
> nner:1852)
>   [8] org.apache.xerces.framework.XMLDocumentScanner$ContentDispatcher.dispatch
> (XMLDocumentScanner$ContentDispatcher:1233)
>   [9] org.apache.xerces.framework.XMLDocumentScanner.parseSome (XMLDocumentScann
> er:380)
>   [10] org.apache.xerces.framework.XMLParser.parse (XMLParser:861)
>   [11] org.jdom.input.SAXBuilder.build (SAXBuilder:258)
>   [12] org.jdom.input.SAXBuilder.build (SAXBuilder:332)
>   [13] org.jdom.input.SAXBuilder.build (SAXBuilder:313)
>   [14] SAXBuilderDemo.testBuilder (SAXBuilderDemo:99)
>   [15] SAXBuilderDemo.main (SAXBuilderDemo:137)
> The actual call from SAXBuilder.startElement occurs in this block of code at
> /*HERE*/
> 
>  if (!attName.startsWith("xmlns")) {
>                 name = attName;
>                 int attSplit;
>                 prefix = "";
>                 if ((attSplit = name.indexOf(":")) != -1) {
>                     prefix = name.substring(0, attSplit);
>                     name = name.substring(attSplit + 1);
>                 }
>                 // Only put attribute in namespace if there is a prefix
>                 if (prefix.equals("")) {
>                     element.addAttribute(
>                         new Attribute(name, atts.getValue(i)));
>                 } else {
>  /*HERE*/        element.addAttribute(
>                         new Attribute(name,
>                                       prefix,
>                                       getNamespaceURI(prefix),
>                                       atts.getValue(i)));
>                 }
> 
> The value of "prefix" which is "xml" is used to construct a URI and the value is
> passed into the Attribute constructor:
> 
>   public Attribute(String name, String prefix, String uri, String value) {
>         this(name, value, Namespace.getNamespace(prefix, uri));
>     }
> 
> Namespace.getNamespace then tries to construct a namespace.  However, the first
> funciton it calls is Verifier.checkNamespacePrefix(prefix), which, as you see in
> the code below does not allow a prefix of xml to be used.  Therefore the program
> throws an exception before Verifier.checkAttributeName is ever called and that is
> where the special cases code is.
> 
> Below, you will find the method from Verifier.  Notice that an xml prefix is
> always wrong.
>   public static final String checkNamespacePrefix(String prefix) {
>         // Manually do rules, since URIs can be null or empty
>         if ((prefix == null) || (prefix.equals(""))) {
>             return null;
>         }
> 
>         // Cannot start with a number
>         char first = prefix.charAt(0);
>         if (isXMLDigit(first)) {
>             return "Namespace prefixes cannot begin with a number";
>         }
>         // Cannot start with a $
>         if (first == '$') {
>             return "Namespace prefixes cannot begin with a dollar sign ($)";
>         }
>         // Cannot start with a -
>         if (first == '-') {
>             return "Namespace prefixes cannot begin with a hyphen (-)";
>         }
>         // Cannot start with a .
>         if (first == '.') {
>             return "Namespace prefixes cannot begin with a period (.)";
>         }
>         // Cannot start with "xml" in any character case
>         if (prefix.toLowerCase().startsWith("xml")) {
>             return "Namespace prefixes cannot begin with " +
>                    "\"xml\" in any combination of case";
>         }
> 
>         // Ensure valid content
>         for (int i=0, len = prefix.length(); i<len; i++) {
>             char c = prefix.charAt(i);
>             if (!isXMLNameCharacter(c)) {
>                 return "Namespace prefixes cannot contain the character \"" +
>                         c + "\"";
>             }
>         }
> 
>         // No colons allowed
>         if (prefix.indexOf(":") != -1) {
>             return "Namespace prefixes cannot contain colons";
>         }
> 
>         // If we got here, everything is OK
>         return null;
>     }
> 
> While one could write code in SAXBuilder to catch the special cases of xml:lang
> and xml:space, the problem is really how the prefix "xml" is being handled in
> Namespace.
> 
> Stacie



More information about the jdom-interest mailing list