[XML-SIG] prepare_input_source and relative path

Sylvain Thénault Sylvain.Thenault at logilab.fr
Mon Feb 7 12:18:48 CET 2005


Hey,

I've been heating a bug which is already registered as #616431 in the
bug tracker. I find it very annoying and I've patched the function to
make it work before noticing a patch was already available. Is there any
reason to still wait to apply it ?
Anyway I've joined to this mail my version of the fix, which fix the
following cases:

- prepare_input_source('relative.xml', '/base') -> /base/relative.xml
  the sf submitted patch fix this one to.

- prepare_input_source('file:relative.xml', '/base') ->
  file:/base/relative.xml


this allow to have a xml file containing relative system identifiers
such as:

  <!ENTITY  plans SYSTEM "file:plans.xml">
  <!ENTITY  chatbot SYSTEM "chatbot.xml">

where parse(open('path to my xml file')) should not fail as it currently
does.

If this patch sounds good to you, I can check it in.

-- 
Sylvain Thénault                               LOGILAB, Paris (France).

http://www.logilab.com   http://www.logilab.fr  http://www.logilab.org

-------------- next part --------------
--- /usr/lib/python2.3/site-packages/_xmlplus/sax/saxutils.py	2004-11-29 13:36:36.000000000 +0100
+++ cvs_work/_xmlplus/sax/saxutils.py	2005-02-07 12:01:42.000000000 +0100
@@ -5,7 +5,7 @@
 $Id: saxutils.py,v 1.35 2004/03/20 07:46:04 fdrake Exp $
 """
 
-import os, urlparse, urllib2, types
+import os, urlparse, urllib, urllib2, types
 import handler
 import xmlreader
 import sys, _exceptions, saxlib
@@ -511,14 +511,24 @@
         source.setByteStream(f)
         if hasattr(f, "name"):
             source.setSystemId(f.name)
-
     if source.getByteStream() is None:
         sysid = source.getSystemId()
-        if os.path.isfile(sysid):
+        # if a base is given, sysid may be relative to it, make the
+        # join before isfile() test
+        if base:
             basehead = os.path.split(os.path.normpath(base))[0]
-            source.setSystemId(os.path.join(basehead, sysid))
-            f = open(sysid, "rb")
+            path = os.path.join(basehead, sysid)
+        else:
+            path = sysid
+        if os.path.isfile(path):
+            source.setSystemId(path)
+            f = open(path, "rb")
         else:
+            # if sysid is an url while base isn't, urljoin will fail, so
+            # insert the protocol identifier into base
+            proto = urlparse.urlparse(sysid)[0]
+            if proto and not urlparse.urlparse(base)[0]:
+                base = '%s:%s' % (proto, urllib.pathname2url(base))
             source.setSystemId(urlparse.urljoin(base, sysid))
             f = urllib2.urlopen(source.getSystemId())
 


More information about the XML-SIG mailing list