You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-dev@xerces.apache.org by Christian Meyer <me...@informatik.tu-muenchen.de> on 2001/10/08 21:03:37 UTC

Problems with Xerces (maybe a bug)

Hello!

I've written a small program to parse xml files. It's for a university project, every xml file has the same structure so please don't wonder why my code looks so bad ;-)
The problem is that the following if loop doesn't extract the value:
if (node.getNodeName().equals("rdf:li")) {
   Element element = (Element)node;
   if (element.hasAttribute("xml:lang")) {
     System.out.println(node.getNodeValue());
   }
}

When I say node.getNodeName() it tells me the correct Name, but NodeValue() just tells null. It shouldn't do that.
The part of the xml file looks like this:
<dc:title>
   <rdf:Alt>
      <rdf:li xml:lang="en">Convergence of some two-level overlapping domain decomposition preconditioners with smoothed aggregation coarse spaces�
      </rdf:li>
   </rdf:Alt>
</dc:title>

Do you have a clue what's wrong with it? Could it be a Xerces bug?
I've attached the full source and the xml file.
Thanks in advance for your help.

Greetings, 
Christian Meyer

Re: Problems with User (maybe pilot error)

Posted by Andy Clark <an...@apache.org>.
Christian Meyer wrote:
> When I say node.getNodeName() it tells me the correct Name, 
> but NodeValue() just tells null. It shouldn't do that.

Actually, it should. 

The DOM specification has a nice table at the beginning that 
lists all of the node types and what values their getNodeType, 
getNodeName, and getNodeValue methods should return. Element 
node values are defined to *always* be null because their text 
value is stored as Text node children of the element. 

Therefore, you need to access the children of the element to 
get the text value of an element. But the good thing is that
the DOM spec requires XML processors to combine adjacent text
nodes into a single node when the tree is built.

Here's some code for you.

  StringBuffer str = new StringBuffer();
  Node child = node.getFirstChild();
  while (child != null) {
    if (child.getNodeType() == Node.TEXT_NODE) {
      str.append(child.getNodeValue());
    }
    child = child.getNextSibling();
  }
  String value = str.toString();

Please note that this takes care of the simplest case. Your
code should be written to handle CDATA sections and entity
references that contain text (and possibly more entity refs).
For example:

  <!ENTITY text1 'Hello'>
  <!ENTITY text2 '&text1;, World'>

  <foo>"&text2;<![CDATA["]]></foo>

Which creates the following DOM tree fragment:

  ELEMENT_NODE "foo", null {
    TEXT_NODE "#text", "\""
    ENTITY_REFERENCE_NODE "text2", null {
      ENTITY_REFERENCE_NODE "text1", null {
        TEXT_NODE "#text", "Hello"
      }
      TEXT_NODE "#text", ", World"
    }
    CDATA_SECTION_NODE "#cdata-section", "\""
  }

If you control the document generation, then the simple case
may work for you. However, if you want to be able to handle
the more complicated case, look into using the DOM iterators
and walkers defined as part of the DOM Level 2 Views module.
They will make your life much easier.

-- 
Andy Clark * IBM, TRL - Japan * andyc@apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-dev-help@xml.apache.org