[xml] building ID/IDREF tables by attaching DTD to an xmlDocPtr??




Hi,

I have an XML file without external or internal subset definitions,
but which should be valid according to a separate DTD. The DTD
contains some attributes marked ID and some marked IDREF. I'm trying
to exploit this fact and use the XPath id() function on the XML file,
and so was looking for a way to make libxml construct the ID/IDREF
tables given an xmlDocPtr, and separately, an xmlDtdPtr. If the DTD is
copied into the XML file (as an internal subset), xmlParseFile results
in an xmlDocPtr that I can use successfully with the id()
function. However, if I build a separate xmlDtdPtr, add it to the doc
as described in Section 10 of the libxml FAQ 

        doc->intSubset = dtd;
        if (doc->children == NULL) xmlAddChild((xmlNodePtr)doc, (xmlNodePtr)dtd);
        else xmlAddPrevSibling(doc->children, (xmlNodePtr)dtd);

and then call xmlValidateDocument(), my resulting xpath id() queries
return empty node sets (adding the DTD and calling
xmlValidateDocument() was my best guess for making this work).

Stepping through with gdb, I found that when evaluating the XPath
function, the call to xmlHashLookup() returns an ID with a null attr
field. xmlAddID (as called by xmlValidateDocument()) creates the ID
with a name field and a null attribute field because it's "operating
in streaming mode". This seems to be as a result of the
xmlValidCtxtPtr, but I'm uncertain of the significance of this. Is the
approach of calling xmlValidateDocument() doomed, and if so, is there
a legitimate way to do this short of modifying the XML file itself?

The best workaround I have at the moment is to use xmlSaveFile() to
write out the doc with the attached DTD, then read it back in.

Thanks very much,
Graham






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]