Hi (and Happy Holidays)

I have a case where a dtd is located in a peer directory of the document, so
that the document does something like


<!DOCTYPE messages SYSTEM "../dtd/messages.dtd">


We then have messages.dtd doing an external entity reference to another dtd,
in this case, language.dtd. The file language.dtd is located in the same
directory as messages.dtd.


<!ENTITY % language SYSTEM "language.dtd">
%language;


Running the document through the parser gets the following error:


DOMCount -v C:/TEMP/p2/docs/small.xml

Fatal Error at (file C:\TEMP\p2\docs\../dtd/messages.dtd, line 6, char 11):
An exception occured!
Type:RuntimeException, Message:Could not open external entity
'C:\TEMP\p2\docs\language.dtd'


I pretty sure (let me know if I'm wrong about this) that language.dtd is in
the correct place, but the file name is being assembled incorrectly.

Here's a patch that shows where I think the problem is, with the
test files attached.

Thanks!
John

diff -c -r xerces-cvs-build/c/src/internal/ReaderMgr.cpp
xerces-ReaderMgr/c/src/internal/ReaderMgr.cpp
*** xerces-cvs-build/c/src/internal/ReaderMgr.cpp       Sat Dec 18 00:48:28 1999
--- xerces-ReaderMgr/c/src/internal/ReaderMgr.cpp       Thu Dec 23 00:28:29 1999
***************
*** 548,556 ****
              // Its just a file path
              if (XMLPlatformUtils::isRelative(sysId))
              {
!                 // Its relative so first store the base directory, if any
!                 if (fBasePath)
!                     expSysId.set(fBasePath);

                  // And then append the relative path
                  expSysId.append(sysId);
--- 548,557 ----
              // Its just a file path
              if (XMLPlatformUtils::isRelative(sysId))
              {
!                 // Its relative so first store the base directory
!                 XMLCh *pathPtr = getCurrentBasePath();
!                 ArrayJanitor<XMLCh> janName(pathPtr);
!                 expSysId.set(pathPtr);

                  // And then append the relative path
                  expSysId.append(sysId);
***************
*** 642,647 ****
--- 643,704 ----
      // Set the reader number to the next available number
      retVal->setReaderNum(fNextReaderNum++);
      return retVal;
+ }
+
+
+ XMLCh* ReaderMgr::getCurrentBasePath()
+ {
+     // Create a buffer for computing the current base path
+     XMLBuffer computedBasePath;
+
+     // Start with the parser base if any external entities return relative
+     if (fBasePath)
+         computedBasePath.set(fBasePath);
+
+     // Get the last external entity.
+     LastExtEntityInfo extInfo;
+     getLastExtEntityInfo(extInfo);
+
+     // If the last external entity is valid, form the base path from it.
+     if (XMLString::stringLen(extInfo.systemId))
+     {
+         // Handle URL systemId values.
+         URL tmpURL;
+         try
+         {
+             tmpURL.setURL(extInfo.systemId);
+             const XMLCh * const urlString = tmpURL.getURL();
+
+             // find the character position after the last slash
+             unsigned int afterSlash = 0;
+             unsigned int index = 0;
+             const XMLCh *urlStringPtr = urlString;
+             while (*urlStringPtr)
+             {
+                 if (*urlStringPtr == chForwardSlash || *urlStringPtr ==
chBackSlash)
+                     afterSlash = index + 1;
+                 urlStringPtr++;
+                 index++;
+             }
+
+             computedBasePath.set(urlString, afterSlash);
+         }
+
+         catch(const MalformedURLException&)
+         {
+             // A file path.
+             if (XMLPlatformUtils::isRelative(extInfo.systemId))
+                 computedBasePath.append(extInfo.systemId);
+             else
+                 computedBasePath.set(extInfo.systemId);
+
+             XMLCh *basePathPtr =
XMLPlatformUtils::getBasePath(computedBasePath.getRawBuffer());
+             ArrayJanitor<XMLCh> janName(basePathPtr);
+             computedBasePath.set(basePathPtr);
+         }
+     }
+
+     return XMLString::replicate(computedBasePath.getRawBuffer());
  }


diff -c -r xerces-cvs-build/c/src/internal/ReaderMgr.hpp
xerces-ReaderMgr/c/src/internal/ReaderMgr.hpp
*** xerces-cvs-build/c/src/internal/ReaderMgr.hpp       Wed Dec 15 23:54:22 1999
--- xerces-ReaderMgr/c/src/internal/ReaderMgr.hpp       Wed Dec 22 23:09:18 1999
***************
*** 199,204 ****
--- 199,205 ----




  // -----------------------------------------------------------------------
      //  Getter methods




  // -----------------------------------------------------------------------
+     XMLCh* getCurrentBasePath();
      const XMLCh* getCurrentEncodingStr() const;
      const XMLEntityDecl* getCurrentEntity() const;
      XMLEntityDecl* getCurrentEntity();

<?xml version='1.0' standalone='no'?>
<!DOCTYPE messages SYSTEM "../dtd/messages.dtd">
<messages version="1">
    <language id="42" area="51">
        <group name="xxy">
            <text id="1">stuff</text>
        </group>
    </language>
</messages>

Attachment: messages.dtd
Description: Binary data

Attachment: language.dtd
Description: Binary data

Attachment: ReaderMgr.patch
Description: Binary data

Reply via email to