You will have to implement a entity resolver.
Write one and plug it into the parser.

What the hell... You can have mine :)
Written for Win32. It implements direct match entities, search paths and
even DTD's in application resource.

Regards

Erik Rydgren
Mandarinen systems AB
Sweden

--- CODE BEGIN ---

#define HANDLE_EXCEPTION(statement) \
  try { \
    statement; \
  } \
  catch (DOM_DOMException& e) { \
    throw cDOMException((edDOMExceptionCode)e.code, e.msg, __FILE__,
__LINE__); \
  } \
  catch (cException&) { \
    throw; \
  } \
  catch (...) { \
    throw cException("Unknown exception", -1, ET_Unspecified, __FILE__,
__LINE__); \
  }

#define HANDLE_EXCEPTION_EXT(pre_statements, statements, post_statements) \
  try { \
    pre_statements; \
    HANDLE_EXCEPTION(statements); \
    post_statements; \
  } \
  catch (cException&) { \
    post_statements; \
    throw; \
  } \
  catch (...) { \
    throw cException("Unknown exception", -1, ET_Unspecified, __FILE__,
__LINE__); \
  }

//
//
****************************************************************************
*****************
// cXML4CEntityResolver
//
****************************************************************************
*****************
//
//##ModelId=3ADEED2E0125
class cXML4CEntityResolver : public EntityResolver
{
  CRITICAL_SECTION sMutex;

  struct sdEntity {
    sdEntity* psNext;
    cDOMString publicId;
    cDOMString systemId;
    cDOMString document;
  };

  sdEntity* m_psHead;
  char* m_pzPath;

public:

  cXML4CEntityResolver()
  {
    InitializeCriticalSection(&sMutex);
    m_psHead = null;
    m_pzPath = null;
  }

  ~cXML4CEntityResolver()
  {
    DeleteCriticalSection(&sMutex);

    while (m_psHead) {
      sdEntity* psLoop = m_psHead;
      m_psHead = m_psHead->psNext;
      delete psLoop;
    }

    delete m_pzPath;
  }

  void addEntity(const char* publicId, const char* systemId, const char*
xmldocument)
  {
    HANDLE_EXCEPTION_EXT(
      EnterCriticalSection(&sMutex);
    ,
      sdEntity* psNewEntity = new sdEntity;

      psNewEntity->publicId = publicId;
      psNewEntity->systemId = systemId;
      psNewEntity->document = xmldocument;

      psNewEntity->psNext = m_psHead;
      m_psHead = psNewEntity;
    ,
      LeaveCriticalSection(&sMutex);
    );
  }

  void addDirToPath(const char* pzDir) {
    HANDLE_EXCEPTION_EXT(
      EnterCriticalSection(&sMutex);
    ,
      if (!m_pzPath) {
        m_pzPath = new char[strlen(pzDir)+2];
        strcpy(m_pzPath, pzDir);
      }
      else {
        bool bFound = false;

        { // Search to see if the dir already is in the path
          char* pzLoop = m_pzPath;

          while (!bFound && pzLoop) {
            // Fetch next dir from path
            char* pzEnd = strchr(pzLoop, ';');
            if (pzEnd) *pzEnd = '\0';

            // Compare the strings disregarding last char if it is a '\'
            int nDirLen = strlen(pzDir);
            int nLoopLen = strlen(pzLoop);
            if (pzDir[nDirLen-1] == '\\')
              nDirLen--;
            if (pzLoop[nLoopLen-1] == '\\')
              nLoopLen--;
            if (nDirLen == nLoopLen && strnicmp(pzLoop, pzDir, nDirLen) ==
0)
              bFound = true;

            if (pzEnd) *pzEnd = ';';
            if (pzEnd)
              pzLoop = pzEnd+1;
            else
              pzLoop = null;
          }
        }

        if (!bFound) { // Add the dir if not found
          char* pzTmp = new char[strlen(m_pzPath)+1+strlen(pzDir)+2];
          strcpy(pzTmp, m_pzPath);
          strcat(pzTmp, ";");
          strcat(pzTmp, pzDir);

          delete m_pzPath;
          m_pzPath = pzTmp;
        }
      }

      // Add traling \ to directory
      if (m_pzPath[strlen(m_pzPath)-1] != '\\')
        strcat(m_pzPath, "\\");
    ,
      LeaveCriticalSection(&sMutex);
    );
  }

  InputSource* resolveEntity
  (
    const XMLCh* const    publicId,
    const XMLCh* const    systemId
  ) {
    InputSource* result = null;

    try {
      EnterCriticalSection(&sMutex);

      {
        // Loop through list searching for entity
        sdEntity* psLoop = m_psHead;
        bool bFound = false;

        while (!bFound && psLoop) {
          if (psLoop->publicId == cDOMString(publicId) && psLoop->systemId
== cDOMString(systemId))
            bFound = true;
          else
            psLoop = psLoop->psNext;
        }

        if (bFound) {
          result = new MemBufInputSource((const XMLByte*)(const char*)
psLoop->document, psLoop->document.getLength(), "xmldocument", false);
        }
      }

      if (!result) { // Not found in list, search in path
        char* pzLoop = m_pzPath;

        while (!result && pzLoop) {
          // Fetch next dir from path
          char* pzEnd = strchr(pzLoop, ';');

          if (pzEnd) *pzEnd = '\0';
          cDOMString oPath(pzLoop);
          if (pzEnd) *pzEnd = ';';

          LocalFileInputSource* fileinput = null;
          try {
            fileinput = new
LocalFileInputSource(DOMString(oPath).rawBuffer(), systemId);
            ifstream in;
            in.open(cDOMString(fileinput->getSystemId()));
            if (in.is_open())
              result = fileinput;
            else
              delete fileinput;
          }
          catch (...) {
            delete fileinput;
            result = null;
          }

          if (pzEnd)
            pzLoop = pzEnd+1;
          else
            pzLoop = null;
        }
      }

      if (!result) { // Not found in path, search in resources
        byte* pbBuffer = NULL;
        cResource oDTDResource;

        try {
          oDTDResource.Select("DTD", cString('"') << (const char*)
cDOMString(systemId) << '"');
          int nBufferLen = oDTDResource.Get(pbBuffer);
          result = new MemBufInputSource((const XMLByte*) pbBuffer,
nBufferLen, "xmldocument", true);
        }
        catch (cException&) {
          delete pbBuffer;
        }
      }

      LeaveCriticalSection(&sMutex);
    }
    catch (cException&) {
      LeaveCriticalSection(&sMutex);
      throw;
    }
    catch (...) {
      throw cException("Unknown exception", -1, ET_Unspecified, __FILE__,
__LINE__);
    }
    return result;
  }
};
--- CODE END ---


-----Original Message-----
From: Ing. Hans Pesata [mailto:[EMAIL PROTECTED]]
Sent: den 14 maj 2002 13:10
To: Xerces Mailinglist
Subject: DTD-/XML-location


Hi !

I am using the WIN32 version of XERCES 1.7.0 with a SAX2-parser to read
XML-files.

I am also using a DTD to validate the XML-files and I realized, that the DTD
has to be located
within the same directory as the XML-file.

I am using the following statement within the XML-files:

<!DOCTYPE myapp SYSTEM "myapp.dtd">

this is a problem for me, because users of my app should be able to save
their files anywhere
and not always in the directory where the DTD is located.

how can I connect the XML-files with the DTD which is located somewhere else
?
I dont want to put the whole path of the DTD into the XML-file.

I tried putting the DTD in a PATH-directory, but it didnt work.

Any help with this would be greatly appreciated,
thanx in advance!

Regards,
Hans Pesata



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to