No subject
Fri Aug 6 17:04:17 PDT 2004
DOMBuilder.buildTree(). As an aside, the "if
(!att.getNodeName().startsWith("xmlns:"))" statement on line 357 seems to be
completely superfluous, since above in line 308, we are assured that namespace
declarations don't get added to the elementAttribute list in the fist place.
But anyway, line 358 causes an Attribute object to be constructed and added to
the current Element object. The problem seems to be that this is always done
with the two argument constructor for Attribute, which expects a local name and
a value, and thus assumes that the attribute is not associated with any
namespace--even if it does have a namespace, indicated by the presence of a
colon. When this constructor calls the canonical, three argument constructor,
the Verifier sees the colon and causes the constructor to throw an
IllegalNameException (line 107 of Attribute.java).
The solution would seem to be that on line 357 of Dombuilder.java, in the
buildTree() method, instead of checking whether the node name starts with
"xmlns:", to check whether the node name contains a colon, and if so, to add the
attribute to the element using a constructor for Attribute that accepts a
namespace, which would be parsed from the namespace-enabled attribute name.
Perhaps something like this:
(replaces DOMBuilder.java 356-360)
/// begin patch
// add the attributes:
if (att.getNodeName().indexOf(":") == -1)
{ // attribute is namespace-free:
element.addAttribute(att.getNodeName(), att.getNodeValue());
}
else
{ // attribute has a namespace:
String qualifiedAttributeName = att.getNodeName();
int splitter = qualifiedAttributeName.indexOf(":");
String prefix = qualifiedAttributeName.substring(0, splitter);
String localName = qualifiedAttributeName.substring(splitter + 1);
String uri = ((Namespace)prefixedNamespaces.get(prefix)).getURI();
String value = att.getNodeValue();
element.addAttribute(new Attribute(localname, prefix, uri, value));
}
/// end patch
and to finish things off, org.jdom.Attribute needs to be imported up at the top.
As far as i can see, that should work. But, be warned, i am not a very active
JDOM developer, so it is possible that i am missing something subtle. Please
let me know what you think.
-Ed
p.s.
If you would like to duplicate the behavior i have reported, you can run the
following program on contents.xml:
/// begin source
import org.jdom.input.SAXBuilder;
import org.jdom.input.DOMBuilder;
import org.jdom.output.XMLOutputter;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
public class BugDemo
extends Object
{
public static void main(String[] args)
throws Exception
{
if (args.length == 1)
{
File file = new File(args[0]);
new BugDemo().demoBug(file);
}
else
{
System.out.println("useage: java BugDemo
<XMLFileName>");
}
}
public void demoBug(File file)
throws Exception
{
System.out.println("\n----------------------------------------\n");
System.out.println("here's an XML file:");
System.out.println("\n----------------------------------------\n");
copyStream(new FileInputStream(file), System.out);
System.out.println("\n----------------------------------------\n");
System.out.println("here's the same file after the SAXBuilder
has its way with it:");
System.out.println("\n----------------------------------------\n");
new XMLOutputter().output(new SAXBuilder().build(file),
System.out);
System.out.println("\n----------------------------------------\n");
System.out.println("here's the same file after the DOMBuilder
has its way with it:");
System.out.println("\n----------------------------------------\n");
new XMLOutputter().output(new DOMBuilder().build(file),
System.out);
System.out.println("\n----------------------------------------\n");
System.out.println("notice that only the xmlns:xsl namespace is
being preserved.");
System.out.println("where did the rest of the namespace
declarations go?");
System.out.println("\n----------------------------------------\n");
}
private void copyStream(InputStream in, OutputStream out)
throws Exception
{
byte[] buffer = new byte[256];
while (true)
{
int bytes = in.read(buffer);
if (bytes == -1) break;
out.write(buffer, 0, bytes);
}
}
}
/// end source
------------
- The happiest of people aren't the ones
who always have the best of everything;
they are the ones who always make the best
of everything they have.
Ed Morehouse
Software Engineer/Evil Genius
The Motley Fool
More information about the jdom-interest
mailing list