You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@xerces.apache.org by "Ing. Hans Pesata" <hp...@chello.at> on 2002/05/14 13:09:38 UTC

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: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


RE: DTD-/XML-location

Posted by Erik Rydgren <er...@mandarinen.se>.
All system id's passes through the entity resolver before the parser does
the default search.
You can thereby hijack any url and redirect the parser to another location.
And YES all children to the DTD must also be resolved properly.
But if you use the path functionality in my resolver all that is handled
automaticly as long as you do not have duplicates in the search path.

/ Erik

-----Original Message-----
From: Ing. Hans Pesata [mailto:hpesata@chello.at]
Sent: den 14 maj 2002 15:50
To: xerces-c-dev@xml.apache.org
Subject: AW: DTD-/XML-location


Hi !

// 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.

Thanx a lot for your help !

I understand that this EntityResolver is called by the parser in case it
cant find an entity (e.g. a DTD) and uses it to provide the full path ?!

I am also using sub-DTDs within my main-DTD, I suppose I have to resolve
these ones too.

Best regards,
Hans Pesata



---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


AW: DTD-/XML-location

Posted by "Ing. Hans Pesata" <hp...@chello.at>.
Hi !

// 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.

Thanx a lot for your help !

I understand that this EntityResolver is called by the parser in case it
cant find an entity (e.g. a DTD) and uses it to provide the full path ?!

I am also using sub-DTDs within my main-DTD, I suppose I have to resolve
these ones too.

Best regards,
Hans Pesata



---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


RE: DTD-/XML-location

Posted by Erik Rydgren <er...@mandarinen.se>.
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:hpesata@chello.at]
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: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org