Validation and duplicate Tags...

I need to validate an XML file and throw an exception when duplicate tags are encountered.

From the w3c spec. I have the impression that when a sub-element is defined in the DTD as :

<!ELEMENT attr_cert (ver,serialNo,own,issuerName,issuerUI,valid,attr+,ext*,sigAlg,sig)>

according to the above, ver, serialNo, etc., should appear only once within a <attr_cert></attr_cert> couple right?

Is there a way to force my parser to throw an exception when a duplicate tag entry is encountered?

I am using Xerces by the way... thanks

[586 byte] By [Jim_Warlock] at [2007-9-26 1:13:47]
# 1
Turning on validation will cause the parser to throw an exception when any deviation from the DTD is encountered. Don't know of any way to selectively validate.
zaneparks at 2007-6-29 0:11:09 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 2
I already tried that :) but had no luckI'm not sure sure though if having an external DTD affects this in any way...
Jim_Warlock at 2007-6-29 0:11:11 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 3

I'm using Xerces too and validating works perfectly. Are you sure validation is on?

This how I do it for the SAXParser:

p.setFeature("http://xml.org/sax/features/validation", true);

You can find more information under 'Futures' in the Xerces home page. If you already know about it excuse me for all this extra information, but, as I said before, I'm using validation and works.

Good luck!

llturro at 2007-6-29 0:11:12 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 4
You have to post your code, Are you using a SAX or DOM parser?
sudhirsrinivasan at 2007-6-29 0:11:17 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 5

I have an XML document with the dtd:

<!ELEMENT attr_cert (ver,serialNo,own,issuerName,issuerUI,valid,attr+,ext*,sigAlg,sig)>

<!ELEMENT ver (#PCDATA)>

<!ELEMENT serialNo (#PCDATA)>

<!ELEMENT own (#PCDATA)>

<!ELEMENT issuerName (#PCDATA)>

<!ELEMENT issuerUI (CDATA)>

<!ELEMENT valid (notBefore,notAfter)>

<!ELEMENT notBefore (CDATA)>

<!ELEMENT notAfter (CDATA)>

<!ELEMENT attr (CDATA)>

<!ELEMENT ext (#PCDATA)>

<!ELEMENT sigAlg (#PCDATA)>

<!ELEMENT sig (CDATA)>

and I'm using the DOM parser ( Xerces version 1.3.0 )

now... the elements have to appear only ONCE...

i turn validation on and most other features for that matter but the parser doesn't complain when I parse an invalid file...

Dunno about the new version of Xerces though... if it is an issue of Xerces1.3.0 then i apologise...

here's my complete code (if needed anyway):

import org.w3c.dom.Node;

import org.w3c.dom.traversal.NodeFilter;

import org.apache.xerces.parsers.DOMParser;

import org.apache.xerces.dom.*;

import org.xml.sax.SAXNotRecognizedException;

import org.xml.sax.SAXNotSupportedException;

import org.xml.sax.SAXException;

import java.io.File;

import java.io.IOException;

/** Attribute Certificate parser/validator class.

* This class implements a DOM parser which parses an XML document

* of the <code>attr_cert</code> Doctype and displays its fields in

* a human-readable format.

*/

public class ParseCert

{

public static void main(String args[]) {

if ((args == null) || (args.length < 1)) {

System.out.println("Usage: java ParseCert <Attribute Certificate Filename>");

System.exit(0);

}

File xml_doc = new File(args[0]);

if ( !(xml_doc.exists()) ) {

System.out.println("File "+ xml_doc.getName() +" does not exist!");

System.exit(-1);

}

try {

//create an object of the Document implementation class

DOMParser parser = new DOMParser();

try {

//include the external DTD

parser.setFeature("http://xml.org/sax/features/external-parameter-entities", true);

//Turn validation on...

parser.setFeature("http://xml.org/sax/features/validation", true);

//enable dynamic validation

parser.setFeature("http://apache.org/xml/features/validation/dynamic", true);

//Parse the document

parser.parse( xml_doc.getName() );

} catch (IOException ioe) {

ioe.printStackTrace();

} catch (SAXNotSupportedException nse) {

nse.printStackTrace();

} catch (SAXNotRecognizedException nre) {

nre.printStackTrace();

}

DocumentImpl document = (DocumentImpl)parser.getDocument();

//check whether we have a valid doctype

if ( !document.getDoctype().getName().equalsIgnoreCase("attr_cert") ) {

System.out.println("File " + xml_doc.getName() +

" is not a valid Attribute Certificate!");

System.exit(-1);

}

//get the root of the XML document

Node root = (Node)document.getDocumentElement();

//instantiate a filter

AllElements allelements = new AllElements();

//create an object of the NodeIterator implementation class

NodeIteratorImpl iterator =

(NodeIteratorImpl)document.createNodeIterator(root,

NodeFilter.SHOW_ALL, (NodeFilter)allelements, true);

//recursively print all elements of the XML document

printElements(iterator);

} catch (Exception e) {

System.out.println("error: " + e);

e.printStackTrace();

System.exit(0);

}

}

//recursive function that prints all elements of the XML document

public static void printElements(NodeIteratorImpl iter)

{

Node n;

System.out.println("--BEGIN ATTRIBUTE CERTIFICATE--");

while ((n = iter.nextNode()) != null) {

if (n.getNodeName().equalsIgnoreCase("ver"))

System.out.println( "Version: \t\t" + n.getLastChild().getNodeValue() );

if (n.getNodeName().equalsIgnoreCase("serialNo"))

System.out.println( "Serial No.: \t\t" + n.getLastChild().getNodeValue() );

if (n.getNodeName().equalsIgnoreCase("own"))

System.out.println( "Owner : \t\t" + n.getLastChild().getNodeValue() );

if (n.getNodeName().equalsIgnoreCase("issuerName"))

System.out.println( "Issuer Name: \t\t" + n.getLastChild().getNodeValue() );

if (n.getNodeName().equalsIgnoreCase("issuerUI"))

System.out.println( "Issuer Unique ID: \t" + n.getLastChild().getNodeValue() );

if (n.getNodeName().equalsIgnoreCase("valid"))

System.out.println( "Validity:");

if (n.getNodeName().equalsIgnoreCase("notBefore"))

System.out.println( "\tnotBefore: \t" + n.getLastChild().getNodeValue() );

if (n.getNodeName().equalsIgnoreCase("notAfter"))

System.out.println( "\tnotAfter: \t" + n.getLastChild().getNodeValue() );

if (n.getNodeName().equalsIgnoreCase("attr"))

System.out.println( "<Biometric Attribute Field>");

if (n.getNodeName().equalsIgnoreCase("ext"))

System.out.println( "<Extension Field>" );

if (n.getNodeName().equalsIgnoreCase("sigAlg"))

System.out.println( "Signature Algorithm: \t" + n.getLastChild().getNodeValue() );

if (n.getNodeName().equalsIgnoreCase("sig"))

System.out.println( "Signature: \n" + n.getLastChild().getNodeValue() );

}

System.out.println("--END ATTRIBUTE CERTIFICATE--");

}

}

//filters elements in the XML document; Returns all the Element nodes

class AllElements implements NodeFilter

{

public short acceptNode (Node n)

{

if (n.getNodeType() == Node.ELEMENT_NODE)

return FILTER_ACCEPT;

return FILTER_SKIP;

}

}

Jim_Warlock at 2007-6-29 0:11:18 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 6

Jim,

it's not the parser version. I have Xerces 1.4.0 and get the same results. I checked my documentation and in the FAQ found this following helpful hint further down:

You can turn validation on and off via methods available on the SAX2 XMLFilter

interface. While only the SAXParser implements the XMLFilter interface, the

methods required for turning on validation are available to both parser classes,

DOM and SAX.

The code snippet below shows how to turn validation on -- assume that parser is an

instance of either org.apache.xerces.parsers.SAXParser or

org.apache.xerces.parsers.DOMParser.parser.setFeature("http://xml.org/sax/features/validation",

true);

IMPORTANT!

Simply turning on validation will not make Xerces actually report the

errors that it detects. For this, you need to implement the

org.xml.sax.ErrorHandler interface and register your implementation with

the parser using the setErrorHandler method.

So, I guess, you have to implement an ErrorHandler.

Hope that helps,

Good luck.

lk555 at 2007-6-29 0:11:20 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...