On 1/1/2010 2:53 AM, David Webber wrote:
Hi,

I am new to Xerces but have successfully got a DOMLSParser to work in C++ -
in as far as I can load a document and find its nodes.

However the

parseURI( pszFilename );

takes forever (over a minute) validating according to a DOCTYPE
statement of
the form:

<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0
Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd";>

I want to replace the reference to the DTD by a reference to a copy on my
machine when calling parseURI( ).

It looks to me like I need to use the DOMLSResourseResolver and DOMLSInput
classes but the documentation requires a level of knowledge and
understanding which I do not have.

Is there any sample code anywhere showing exactly how to do this?
It's pretty straightforward:

1. Derive your own class from DOMLSResourceResolver and implement the resolveResource() function. The implementation should just compare the public ID parameter with the public ID of the DTD you want to load locally:

#include "xercesc/dom/DOMLSResourceResolver.h"
#include "xercesc/util/XMLString.h"
#include "xercesc/framework/Wrapper4InputSource.hpp"
#include "xercesc/framework/LocalFileInputSource.hpp"


class myResolver : public DOMLSResourceResolver {
 public:
  myResolver();
  virtual ~myResolver();

  virtual DOMLSInput* resolveResource(const XMLCh* const    resourceType
                                      , const XMLCh* const  namespaceUri
                                      , const XMLCh* const  publicId
                                      , const XMLCh* const  systemId
                                      , const XMLCh* const  baseURI);
 private:
  const XMLCh* m_publicID;
  const char* m_fileName;
};

myResolver::myResolver()
: m_publicID(XMLString::transcode("-//Recordare//DTD MusicXML 1.0 Partwise//EN")),
      m_fileName("/home/dbertoni/dtds/partwise.dtd") {
}

myResolver::~myResolver() {
    XMLString::release(&m_publicID);
}

DOMLSInput* myResolver::resolveResource(const XMLCh* const    resourceType
, const XMLCh* const namespaceUri
                                        , const XMLCh* const    publicId
                                        , const XMLCh* const    systemId
                                        , const XMLCh* const    baseURI) {

  if (!XMLString::compareString(m_publicId, publicId)) {
    return new Wrapper4InputSource(new LocalFileInputSource(m_fileName));
  } else {
    return 0;
  }
}

2. Install your resolver into the parser:

myResolver resolver;

const XMLCh* parameter = XMLString::transcode("resource-resolver");

parser->getDomConfig()->setParameter(parameter, &resolver);

XMLString::release(&parameter);

Dave

Reply via email to