[jdom-interest] moving namespaces up

Vladimir Grishchenko VGrishchenko at serena.com
Mon Jun 18 10:13:25 PDT 2001

Hi again,

I spent some time coding to come up with a solution. To my
disappointment I've discovered there's no setNamespace() method in
Element, and there's also no setName() which I didn't really need.
I've read a discussion
on this mailing list that took place some time ago and kind of see
why it is so. While not needed in most of the cases I think there's
nothing wrong with the methods mentioned, at least with the namespace
one. Without them I'd have to call getCopy() on each element in my tree
to modify its namespaces prefix, this is really bad performance wise since
recursively clones the whole subtree under this Element (correct me if
I'm wrong). What an overkill, I just wanted to change element's namespace
prefix but have to end up with cloning the tree multiple times. So I went
and added setNamespace() to both Element and Attribute. Here's a "solution"
to my problem, may be you can point me to potential pitfalls I could have
introduced here.



import org.jdom.*;
import org.jdom.output.*;

import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

public class RootNamespaceDocument extends Document
  private Map namespaces;
  private List sorted;

  public RootNamespaceDocument(Document other)
    super(other.getRootElement(), other.getDocType());
    namespaces = new HashMap(20);
    sorted = new ArrayList(10);
    Iterator i = sorted.iterator();
    while (i.hasNext())
      getRootElement().addNamespaceDeclaration((Namespace) i.next());

  private void renameNamespaces(Element root)
    Namespace n = root.getNamespace();
    if (!n.equals(Namespace.NO_NAMESPACE))
      //had to change org.jdom.Element to do this
    List l = root.getAttributes();
    Attribute a;
    for (int i = 0; i < l.size(); i++)
      a = (Attribute) l.get(i);
      n = a.getNamespace();
      if (!n.equals(Namespace.NO_NAMESPACE))
        //had to change org.jdom.Attribute to do this
    l = root.getChildren();
    for (int i = 0; i < l.size(); i++)
      renameNamespaces((Element) l.get(i));

  private Namespace getNewNamespace(String uri)
    Namespace newns = (Namespace) namespaces.get(uri);
    if (newns == null)
      newns = Namespace.getNamespace("ns" + namespaces.size(), uri);
      namespaces.put(uri, newns);
    return newns;

  public static void main(String[] args) throws Exception
    Namespace ns1 = Namespace.getNamespace("A", "FOO:");
    Namespace ns2 = Namespace.getNamespace("B", "BAR:");
    Namespace ns3 = Namespace.getNamespace("C", "BAZ:");
    Namespace ns4 = Namespace.getNamespace("D", "ZAB:");
    Namespace ns5 = Namespace.getNamespace("E", "RAB:");
    Namespace ns6 = Namespace.getNamespace("F", "OOF:");

    Document d = new Document(new Element("root_element", ns6));

    d.getRootElement().addContent(new Element("child1", ns1)
      .addAttribute(new Attribute("xxx", "yyy", ns3)));
    d.getRootElement().addContent(new Element("child2", ns2)
      .addAttribute(new Attribute("zzz", "ooo", ns4)));
    d.getRootElement().addContent(new Element("child3", ns1)
      .addAttribute(new Attribute("ggg", "hhh", ns2)));
    XMLOutputter outputter = new XMLOutputter("   ", true);
    outputter.output(d, System.out);
    RootNamespaceDocument rnd = new RootNamespaceDocument(d);
    outputter.output(rnd, System.out);


> -----Original Message-----
> From: Elliotte Rusty Harold [mailto:elharo at metalab.unc.edu]
> Sent: Friday, June 15, 2001 5:22 PM
> To: Vladimir Grishchenko; 'jdom-interest at jdom.org'
> Subject: Re: [jdom-interest] moving namespaces up
> At 4:28 PM -0700 6/15/01, Vladimir Grishchenko wrote:
> >Hello,
> >
> >Here is a dumb question but I need this functionality for my project.
> >I looked briefly at JDOM api and couldn't find a way to do 
> the following:
> >
> >Say, I have an XML doc stored as:
> >
> ><root>
> >    <A:child1 xmlns:A="FOO:"/>
> >    <B:child2 xmlns:B="BAR:"/>
> ></root>
> >
> >I read it in via SAXBuilder and I want it to be outputted as:
> >
> ><root xmlns:A="FOO:" xmlns:B="BAR:">
> >   <A:child1/>
> >   <B:child2/>
> ><root/>
> >
> >Basically I need all namespace declarations to be moved up, possibly
> >changing prefix names if there's any prefix name collisions.
> >
> I doubt this will be a part of the JDOM 1.0 core. We used to do 
> something like this, but then we were convinced that it was 
> impossible to do in the general case because of the difficulty of 
> recognizing when prefixes were and were not used in attribute values 
> and element content.
> -- 
> +-----------------------+------------------------+-------------------+
> | Elliotte Rusty Harold | elharo at metalab.unc.edu | Writer/Programmer |
> +-----------------------+------------------------+-------------------+
> |                  The XML Bible (IDG Books, 1999)                   |
> |              http://metalab.unc.edu/xml/books/bible/               |
> |   http://www.amazon.com/exec/obidos/ISBN=0764532367/cafeaulaitA/   |
> +----------------------------------+---------------------------------+
> |  Read Cafe au Lait for Java News:  http://metalab.unc.edu/javafaq/ |
> |  Read Cafe con Leche for XML News: http://metalab.unc.edu/xml/     |
> +----------------------------------+---------------------------------+

This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. Any unauthorized review, use, disclosure or distribution
is prohibited. If you are not the intended recipient, please contact
the sender by reply e-mail and destroy all copies of the original

More information about the jdom-interest mailing list