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
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;
}
}