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 Jessica Perry Hekman <jp...@arborius.net> on 2000/11/08 21:17:17 UTC

More dynamic validation troubles

Thanks for all this list's help last time. I hope I can presume some more.

I'm having more problems with Xerces1.2.0 when I try to convince it to
dynamically validate trees. In this case, I have discovered the
relevant lines of code which, when commented out, make things
work. I'm just touching base with the list to make sure I didn't miss
anything: why was this code here in the first place?

It's going to take a bit of explanation, so please bear with me. I'm
sure you all find this stuff as fascinating as I do, anyways, so it
shouldn't be a trial :)

I wrote a class which, given an XML file, parses it, hangs on to the
parser, and then looks at which children are legal (valid) inside
various elements. In the simplest case, the XML document looks like
this:

 <?xml version="1.0" ?>
 <!DOCTYPE list SYSTEM "list.dtd">
 <list>
  <elem/>
  <elem/>
  <elem/>
  <elem/>
 </list>

The DTD looks like this:

 <!ELEMENT list (elem, elem, elem, elem) >
 <!ELEMENT elem EMPTY >

When I ask Xerces if this document is valid, it says it is.

Then I ask my class to tell me what elements are valid inside the root
element (list):

    public void test () throws Exception {
	DocumentImpl doc = (DocumentImpl) this.parser.getDocument();
	Element root = (Element) doc.getDocumentElement();
	String[] names = this.getChildNames(root);

	for (int i = 0; i < names.length; i++) {
	    System.out.println("name " + names[i]);
	}
    }

    public String[] getChildNames(Node n) throws Exception {
     	XMLValidator val = this.parser.getValidator();
	InsertableElementsInfo info =
	    this.makeInfoObjectWithNewChild (n);
	int failedIndex =
	    val.whatCanGoHere
	    (this.getElementDeclIndex
	     (this.getElementIndex(n.getNodeName())),
	     true, info);
	String[] names = new String[info.possibleChildren.length];

	if (failedIndex != -1)
	    throw(new Exception("failed to find possible children for "
				+ ((Element) n).getTagName()));

	for (int i = 0; i < info.possibleChildren.length; i++) {
	    names[i] = this.qnameToString(info.possibleChildren[i]);
	}

	return(names);
    }

There's clearly a lot of boilerplate missing here; available on
request. Okay, so I run this, and I get:

[jphekman@pendaran package]$ java com.ememes.xmlmemes.BuildXML ~/tmp/list.xml
name elem
name null

Funny. It should tell me that I can have four "elem"s, not one. When I
comment out some code in DFAContentModel.java (more on that later), I
get what I expect:

[jphekman@pendaran package]$ java com.ememes.xmlmemes.BuildXML ~/tmp/list.xml
name elem
name elem
name elem
name elem
name null

I'm not sure why the null is there, since other content models don't
seem to produce it, and this content model doesn't have a "+" or "*"
or "?" in it (any of which I would expect to require a null), so maybe
there's some other logic going wrong; I'm not sure.

Phew. Okay. So the relevant lines in DFAContentModel.java are:

            // See if the current leaf node's element index is in the list
            int inIndex = 0;
            for (; inIndex < fElemMapSize; inIndex++)
            {
		// I commented out this chunk:
        	/*
                if (fDTD) {
                    if (fElemMap[inIndex].rawname == element.rawname) {
                        break;
                    }
                }
                else {
                    if (fElemMap[inIndex].uri == element.uri &&
                        fElemMap[inIndex].localpart == element.localpart &&
                        fElemMapType[inIndex] == fLeafListType[outIndex] )
                        break;
			}
              */
            }

            // If it was not in the list, then add it, if not the EOC node
            if (inIndex == fElemMapSize) {

You can see what I commented. The code seems to be making sure that it
doesn't put the same element into its list multiple times, but in fact
is doing the wrong thing when we expect to see a set number of a
certain element.

I reran my original validity test with this code commented out, and
was told that the original document is still valid. So that, at least,
seems to work both ways.

Any thoughts? I know this isn't worth looking into in terms of fixing
Xerces1.x, on account of the imminence of Xerces2, but I'm concerned
that commenting this code out may have horribly broken something which
I won't discover until later.

Thanks,

Jessica