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?
>
>