You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xerces.apache.org by Dick Deneer <di...@donkeydevelopment.com> on 2005/12/20 08:26:30 UTC

Current Element Node

I am trying to get the current elementNode ( by means of the property 
"http://apache.org/xml/properties/dom/current-element-node" ) when the 
domparser reports an error, but I am getting a null node as result.
Using xerces 2.71 wiyh JAXP interface.
Can I use this property for this situation?



Program:
import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class TestCurrentNode implements ErrorHandler
{

	DocumentBuilderFactory dbf = null;

	public Document parseDom(File xmlFile)
	{

		//create a SchemaFactory that conforms to W3C XML Schema

		// get a DOM factory
		dbf = DocumentBuilderFactory.newInstance();
		// configure the factory
		dbf.setNamespaceAware(true);
		dbf.setValidating(true);
		dbf.setAttribute(
			"http://apache.org/xml/features/dom/defer-node-expansion",
			Boolean.FALSE);

		DocumentBuilder db;
		try
		{
			db = dbf.newDocumentBuilder();
			db.setErrorHandler(this);
			System.out.println(this.getClass() + " parsetoDom");
			return db.parse(xmlFile);
		}
		catch (ParserConfigurationException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (SAXException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}

	public void warning(SAXParseException arg0) throws SAXException
	{
		System.out.println("instance warning " + arg0);

	}

	public void error(SAXParseException arg0) throws SAXException
	{
		System.out.println("instance error " + arg0);
		Node node = null;

		node =
			(Node) dbf.getAttribute(
				"http://apache.org/xml/properties/dom/current-element-node");

		if (node != null)
		{
			System.out.println("node = " + node.getNodeName());
		}
		else
			System.out.println("Node = null");
		//e.printStackTrace();

		//System.out.println("validator error " + arg0);
		//System.out.println("cause " + arg0.getCause());

	}

	public void fatalError(SAXParseException arg0) throws SAXException
	{
		System.out.println("instance fatal " + arg0);

	}
	//	DefaultHandler contain no-op implementations for all SAX events.
	// This class should override methods to capture the events of 
interest.

	public static void main(String[] args)
	{
		System.out.println("Progrma  started");

		File xmlFile = new File(args[0]);
		if (!xmlFile.exists())
		{
			System.out.println("cannot find xml file " + args[0]);
			System.exit(0);
		}

		TestCurrentNode testSax = new TestCurrentNode();
		testSax.parseDom(xmlFile);
		System.out.println("Program ended");

	}
}


Input
<?xml version="1.0"?>
<!DOCTYPE notes [
   <!ELEMENT note (heading,body,sub)>
   <!ATTLIST note from CDATA #REQUIRED>
   <!ATTLIST note to CDATA #REQUIRED>
   <!ELEMENT to      (#PCDATA)>
   <!ELEMENT from    (#PCDATA)>
   <!ELEMENT heading (#PCDATA)>
   <!ELEMENT body    (#PCDATA)>
   <!ELEMENT sub   (#PCDATA)>
]>
<note from="Piet" to="Sint">
   <heading>this is the heading</heading>
   <bodsy>this is the body</bodsy>
</note>

Output
Progrma  started
class TestCurrentNode parsetoDom
instance error org.xml.sax.SAXParseException: Document root element 
"note", must match DOCTYPE root "notes".
Node = null
instance error org.xml.sax.SAXParseException: Element type "bodsy" must 
be declared.
Node = null
instance error org.xml.sax.SAXParseException: The content of element 
type "note" must match "(heading,body,sub)".
Node = null
Program ended

Re: Current Element Node

Posted by Dick Deneer <di...@donkeydevelopment.com>.
Because the minimum response I did  some more research to get this 
working. I first tried to switch to the standard method to setup of a 
dom parser:
  System.setProperty(DOMImplementationRegistry.PROPERTY,
                 "org.apache.xerces.dom.DOMXSImplementationSourceImpl");
         DOMImplementationRegistry registry = DOMImplementationRegistry
                 .newInstance();
         DOMImplementationLS impl = (DOMImplementationLS) registry
                 .getDOMImplementation("psvi");
         LSParser parser = impl
                 .createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, 
null);
But it did gave me success. I was not able to set the deferred dom 
expansion property to false. The LSParser is not an instance of 
DOMParser, but is a  DOMParserImpl.

At last I just swithed to the method by instantiating a a DOMParser 
directy:
XMLParserConfiguration config = new XIncludeAwareParserConfiguration();
         config.setProperty(
                 
"http://apache.org/xml/properties/internal/grammar-pool",
                 grammarPool);

         parser = new DOMParserExt(config);

         parser.setFeature(
                 
"http://apache.org/xml/features/dom/defer-node-expansion",
                 false); // otherwise parser.getCurrentNode() == null

I added an errorHandler and everything worked fine.
I really wonder if anyone have made this working by JAXP of through the 
LSParser.

I all started this because Xerces can not revalidate a dom XMLdocument 
with an attached DTD. Revalidation with schemas is no problem, but 
revalidation with DTD just gives "random" errors. There is no other way 
than serialize the document and feed it again to the parser. I did not 
found a method to feed a Sax or DomParser with just the dom document.
I was hoping that the current-element-node feauture would gave me the 
same precision of error location as the "revalidation" feature gives. 
Again I was disappointed. When error are encountered in text values 
(for instance if they are not a valid value of an enumeration) the 
current-element-node is "null" again. And errors in attributes, are 
pointing to the ownerElement.

If I am wrong in my conclusions please let me know.

Regards
Dick Deneer


Dick Deneer heeft op dinsdag, 20 dec 2005 om 08:26 (Europe/Amsterdam) 
het volgende geschreven:

> I am trying to get the current elementNode ( by means of the property 
> "http://apache.org/xml/properties/dom/current-element-node" ) when the 
> domparser reports an error, but I am getting a null node as result.
> Using xerces 2.71 wiyh JAXP interface.
> Can I use this property for this situation?
>
>