Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
e4679cb4
Commit
e4679cb4
authored
Oct 31, 2004
by
Andreas Jung
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- Collector #1443: Applied patch by Simon Eisenmann that reimplements
the XML parser used in WebDAV fixing a memory leak.
parent
d283258e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
82 additions
and
331 deletions
+82
-331
doc/CHANGES.txt
doc/CHANGES.txt
+13
-9
lib/python/webdav/xmltools.py
lib/python/webdav/xmltools.py
+69
-322
No files found.
doc/CHANGES.txt
View file @
e4679cb4
...
...
@@ -22,23 +22,27 @@ Zope Changes
- Port ZOPE_CONFIG patch from Zope 2.7 to Zope 2.8
after Zope 2.8a1
Bugs fixed
- docutils: updated to V 0.3.5. The Zope core now contains a full copy
of
the docutils package except some GPLed files which can not be included
- docutils: updated to V 0.3.5. The Zope core now contains a full copy
of
the docutils package except some GPLed files which can not be included
with the Zope distribution due to license constraints on svn.zope.org.
- docutils: moved from lib/python/docutils to lib/python/third_party/docutils
- docutils: moved from lib/python/docutils to
lib/python/third_party/docutils
- Collector #1557/OFS.Image: Introducing new 'alt' property. The 'alt'
attribute
is no longer taken from the 'title' property but from the new 'alt' property.
The border="0" attribute is no longer part of the HTML output except specified
otherwise.
- Collector #1557/OFS.Image: Introducing new 'alt' property. The 'alt'
attribute is no longer taken from the 'title' property but from the new
'alt' property. The border="0" attribute is no longer part of the HTML
o
utput except specified o
therwise.
- Collector #1511: made IPCServer show up in the Control Panel under "Network Services"
- Collector #1511: made IPCServer show up in the Control Panel under
"Network Services"
- Collector #1443: Applied patch by Simon Eisenmann that reimplements
the XML parser used in WebDAV fixing a memory leak.
Zope 2.8a1
...
...
lib/python/webdav/xmltools.py
View file @
e4679cb4
##############################################################################
#
# Copyright (c) 200
1
Zope Corporation and Contributors. All Rights Reserved.
# Copyright (c) 200
2
Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
...
...
@@ -11,347 +11,94 @@
#
##############################################################################
"""WebDAV XML parsing tools. Note that this module does just
enough for the purposes of DAV - it is not intended as a
general xml toolkit, and will probably eventually go away
in favor of a standard xml package once some issues are
worked out."""
__version__
=
'$Revision: 1.16 $'
[
11
:
-
2
]
"""
WebDAV XML request parsing tool using xml.minidom as xml parser.
Code contributed by Simon Eisenmann, struktur AG, Stuttgart, Germany
"""
import
Shared.DC.xml.xmllib
from
Acquisition
import
Implicit
__version__
=
'$Revision: 1.15.2.1 $'
[
11
:
-
2
]
"""
TODO:
type_document
=
0
type_element
=
1
type_attribute
=
2
type_text
=
3
type_cdata
=
4
type_entityref
=
5
type_entity
=
6
type_procinst
=
7
type_comment
=
8
type_notation
=
9
- Check the methods Node.addNode, Node.remap and Node del_attr
and find out if some code uses/requires these methods.
=> If yes implement them, else forget them.
NOTE: So far i didn't have any problems.
If you have problems please report them.
class
Node
(
Implicit
):
"""Common base class for Node objects."""
__name__
=
''
__value__
=
''
__attrs__
=
[]
__nodes__
=
[]
__nskey__
=
''
"""
def
name
(
self
):
return
self
.
__name__
def
attrs
(
self
):
return
self
.
__attrs__
def
value
(
self
):
return
self
.
__value__
def
nodes
(
self
):
return
self
.
__nodes__
def
nskey
(
self
):
return
self
.
__nskey__
from
xml.dom
import
minidom
def
addNode
(
self
,
node
):
self
.
__nodes__
.
append
(
node
.
__of__
(
self
))
def
namespace
(
self
):
nskey
=
self
.
__nskey__
while
1
:
if
hasattr
(
self
,
'__nsdef__'
):
val
=
self
.
__nsdef__
.
get
(
nskey
,
None
)
if
val
is
not
None
:
return
val
if
not
hasattr
(
self
,
'aq_parent'
):
return
''
self
=
self
.
aq_parent
def
elements
(
self
,
name
=
None
,
ns
=
None
):
nodes
=
[]
name
=
name
and
name
.
lower
()
for
node
in
self
.
__nodes__
:
if
node
.
__type__
==
type_element
and
\
((
name
is
None
)
or
((
node
.
__name__
.
lower
())
==
name
))
and
\
((
ns
is
None
)
or
(
node
.
namespace
()
==
ns
)):
nodes
.
append
(
node
)
class
Node
:
""" our nodes no matter what type """
node
=
None
def
__init__
(
self
,
node
):
self
.
node
=
node
def
elements
(
self
,
name
=
None
,
ns
=
None
):
nodes
=
[
Node
(
n
)
for
n
in
self
.
node
.
childNodes
if
n
.
nodeType
==
n
.
ELEMENT_NODE
and
\
((
name
is
None
)
or
((
n
.
localName
.
lower
())
==
name
))
and
\
((
ns
is
None
)
or
(
n
.
namespaceURI
==
ns
))
]
return
nodes
def
__getitem__
(
self
,
n
):
return
self
.
__nodes__
[
n
]
def
qname
(
self
):
ns
=
self
.
__nskey__
if
ns
:
ns
=
'%s:'
%
ns
return
'%s%s'
%
(
ns
,
self
.
__name__
)
return
'%s%s'
%
(
self
.
namespace
(),
self
.
name
())
def
addNode
(
self
,
node
):
# XXX: no support for adding nodes here
raise
NotImplementedError
,
'addNode not implemented'
def
toxml
(
self
):
return
self
.
__value__
return
self
.
node
.
toxml
()
def
strval
(
self
):
return
self
.
toxml
()
class
Document
(
Node
):
def
__init__
(
self
,
encoding
=
'utf-8'
,
stdalone
=
''
):
self
.
__name__
=
'document'
self
.
__nodes__
=
[]
self
.
encoding
=
encoding
self
.
stdalone
=
stdalone
self
.
document
=
self
def
toxml
(
self
):
result
=
[
'<?xml version="1.0" encoding="%s"?>'
%
self
.
encoding
]
for
node
in
self
.
__nodes__
:
result
.
append
(
node
.
toxml
())
return
''
.
join
(
result
)
class
Element
(
Node
):
__type__
=
type_element
def
__init__
(
self
,
name
,
attrs
=
{}):
self
.
__name__
=
name
self
.
__attrs__
=
[]
self
.
__nodes__
=
[]
self
.
__nsdef__
=
{}
self
.
__nskey__
=
''
for
name
,
val
in
attrs
.
items
():
attr
=
Attribute
(
name
,
val
)
self
.
__attrs__
.
append
(
attr
)
self
.
ns_parse
()
parts
=
self
.
__name__
.
split
(
':'
)
if
len
(
parts
)
>
1
:
self
.
__nskey__
=
parts
[
0
]
self
.
__name__
=
':'
.
join
(
parts
[
1
:])
def
ns_parse
(
self
):
nsdef
=
self
.
__nsdef__
=
{}
for
attr
in
self
.
attrs
():
name
,
val
=
attr
.
name
(),
attr
.
value
()
key
=
name
.
lower
()
if
key
[:
6
]
==
'xmlns:'
:
nsdef
[
name
[
6
:]]
=
val
elif
key
==
'xmlns'
:
nsdef
[
''
]
=
val
def
fixup
(
self
):
self
.
__attrs__
=
map
(
lambda
n
,
s
=
self
:
n
.
__of__
(
s
),
self
.
__attrs__
)
def
get_attr
(
self
,
name
,
ns
=
None
,
default
=
None
):
for
attr
in
self
.
__attrs__
:
if
attr
.
name
()
==
name
and
(
ns
is
None
)
or
(
ns
==
attr
.
namespace
()):
return
attr
return
default
def
name
(
self
):
return
self
.
node
.
localName
def
attrs
(
self
):
return
self
.
node
.
attributes
def
value
(
self
):
return
self
.
node
.
nodeValue
def
nodes
(
self
):
return
self
.
node
.
childNodes
def
nskey
(
self
):
return
self
.
node
.
namespaceURI
def
namespace
(
self
):
return
self
.
nskey
()
def
del_attr
(
self
,
name
):
attrs
=
[]
for
attr
in
self
.
__attrs__
:
if
attr
.
name
()
!=
name
:
attrs
.
append
(
attr
)
self
.
__attrs__
=
attrs
def
remap
(
self
,
dict
,
n
=
0
,
top
=
1
):
# The remap method effectively rewrites an element and all of its
# children, consolidating namespace declarations into the element
# on which the remap function is called and fixing up namespace
# lookup structures.
nsval
=
self
.
namespace
()
if
not
nsval
:
nsid
=
''
elif
not
dict
.
has_key
(
nsval
):
nsid
=
'ns%d'
%
n
dict
[
nsval
]
=
nsid
n
=
n
+
1
else
:
nsid
=
dict
[
nsval
]
for
attr
in
self
.
__attrs__
:
dict
,
n
=
attr
.
remap
(
dict
,
n
,
0
)
for
node
in
self
.
elements
():
dict
,
n
=
node
.
remap
(
dict
,
n
,
0
)
attrs
=
[]
for
attr
in
self
.
__attrs__
:
name
=
attr
.
__name__
if
not
(((
len
(
name
)
>=
6
)
and
(
name
[:
6
]
==
'xmlns:'
))
or
\
name
==
'xmlns'
):
attrs
.
append
(
attr
)
self
.
__attrs__
=
attrs
self
.
__nsdef__
=
{}
self
.
__nskey__
=
nsid
if
top
:
attrs
=
self
.
__attrs__
keys
=
dict
.
keys
()
keys
.
sort
()
for
key
in
keys
:
attr
=
Attribute
(
'xmlns:%s'
%
dict
[
key
],
key
)
attrs
.
append
(
attr
.
__of__
(
self
))
self
.
__attrs__
=
attrs
self
.
ns_parse
()
return
dict
,
n
def
toxml
(
self
):
qname
=
self
.
qname
()
result
=
[
'<%s'
%
qname
]
for
attr
in
self
.
__attrs__
:
result
.
append
(
attr
.
toxml
())
if
not
self
.
__value__
and
not
self
.
__nodes__
:
result
.
append
(
'/>'
)
else
:
result
.
append
(
'>'
)
for
node
in
self
.
__nodes__
:
result
.
append
(
node
.
toxml
())
result
.
append
(
'</%s>'
%
qname
)
return
''
.
join
(
result
)
def
strval
(
self
,
top
=
1
):
if
not
self
.
__value__
and
not
self
.
__nodes__
:
return
''
result
=
map
(
lambda
n
:
n
.
toxml
(),
self
.
__nodes__
)
return
''
.
join
(
result
)
class
Attribute
(
Node
):
__type__
=
type_attribute
def
__init__
(
self
,
name
,
val
):
self
.
__name__
=
name
self
.
__value__
=
val
self
.
__nskey__
=
''
parts
=
name
.
split
(
':'
)
if
len
(
parts
)
>
1
:
pre
=
parts
[
0
].
lower
()
if
not
(
pre
in
(
'xml'
,
'xmlns'
)):
self
.
__nskey__
=
parts
[
0
]
self
.
__name__
=
':'
.
join
(
parts
[
1
:])
# XXX: no support for removing attributes
# zope can calls this after remapping to remove namespace
# haven't seen this happening though
return
None
def
remap
(
self
,
dict
,
n
=
0
,
top
=
1
):
nsval
=
self
.
namespace
()
if
not
nsval
:
nsid
=
''
elif
not
dict
.
has_key
(
nsval
):
nsid
=
'ns%d'
%
n
dict
[
nsval
]
=
nsid
n
=
n
+
1
else
:
nsid
=
dict
[
nsval
]
self
.
__nskey__
=
nsid
return
dict
,
n
def
toxml
(
self
):
ns
=
self
.
__nskey__
if
ns
:
ns
=
'%s:'
%
ns
return
' %s%s="%s"'
%
(
ns
,
self
.
__name__
,
self
.
__value__
)
class
Text
(
Node
):
__name__
=
'#text'
__type__
=
type_text
def
__init__
(
self
,
val
):
self
.
__value__
=
val
def
toxml
(
self
):
return
escape
(
self
.
__value__
)
class
CData
(
Node
):
__type__
=
type_cdata
__name__
=
'#cdata'
def
__init__
(
self
,
val
):
self
.
__value__
=
val
def
toxml
(
self
):
return
'<![CDATA[%s]]>'
%
self
.
__value__
class
EntityRef
(
Node
):
__name__
=
'#entityref'
__type__
=
type_entityref
def
__init__
(
self
,
val
):
self
.
__value__
=
val
def
toxml
(
self
):
return
'&%s;'
%
self
.
__value__
class
Entity
(
Node
):
__name__
=
'#entity'
__type__
=
type_entity
def
__init__
(
self
,
name
,
pubid
,
sysid
,
nname
):
self
.
__value__
=
val
def
toxml
(
self
):
return
''
class
ProcInst
(
Node
):
__type__
=
type_procinst
def
__init__
(
self
,
name
,
val
):
self
.
__name__
=
name
self
.
__value__
=
val
def
toxml
(
self
):
return
'<?%s %s?>'
%
(
self
.
__name__
,
self
.
__value__
)
class
Comment
(
Node
):
__name__
=
'#comment'
__type__
=
type_comment
def
__init__
(
self
,
val
):
self
.
__value__
=
val
def
toxml
(
self
):
return
'<!--%s-->'
%
self
.
__value__
# XXX: this method is used to do some strange remapping of elements
# and namespaces .. not sure how to do this with minidom
# and if this is even required for something
# zope calls this to change namespaces in PropPatch and Lock
return
{},
0
def
__repr__
(
self
):
if
self
.
namespace
():
return
"<Node %s (from %s)>"
%
(
self
.
name
(),
self
.
namespace
())
else
:
return
"<Node %s>"
%
self
.
name
()
class
XmlParser
:
""" simple wrapper around minidom to support the required
interfaces for zope.webdav
"""
class
XmlParser
(
Shared
.
DC
.
xml
.
xmllib
.
XMLParser
):
dom
=
None
def
__init__
(
self
):
Shared
.
DC
.
xml
.
xmllib
.
XMLParser
.
__init__
(
self
)
self
.
root
=
None
self
.
node
=
None
def
parse
(
self
,
data
):
# prepending a XML preample to make xmllib happy
# (Collector #863)
if
not
data
.
startswith
(
"<?xml"
):
data
=
'<?xml version="1.0" ?>
\
n
'
+
data
self
.
feed
(
data
)
self
.
close
()
return
self
.
root
def
add
(
self
,
node
):
self
.
node
.
addNode
(
node
)
def
push
(
self
,
node
):
self
.
node
.
addNode
(
node
)
self
.
node
=
self
.
node
.
__nodes__
[
-
1
]
def
pop
(
self
):
self
.
node
=
self
.
node
.
aq_parent
def
unknown_starttag
(
self
,
name
,
attrs
):
node
=
Element
(
name
,
attrs
)
self
.
push
(
node
)
# Fixup aq chain!
self
.
node
.
fixup
()
def
unknown_endtag
(
self
,
name
):
self
.
pop
()
def
handle_xml
(
self
,
encoding
,
stdalone
):
self
.
root
=
Document
(
encoding
,
stdalone
)
self
.
node
=
self
.
root
def
handle_doctype
(
self
,
tag
,
pubid
,
syslit
,
data
):
pass
def
handle_entity
(
self
,
name
,
strval
,
pubid
,
syslit
,
ndata
):
self
.
add
(
Entity
(
name
,
strval
,
pubid
,
syslit
,
ndata
))
def
handle_cdata
(
self
,
data
):
self
.
add
(
CData
(
data
))
def
handle_proc
(
self
,
name
,
data
):
self
.
add
(
ProcInst
(
name
,
data
))
def
handle_comment
(
self
,
data
):
self
.
add
(
Comment
(
data
))
def
handle_data
(
self
,
data
):
self
.
add
(
Text
(
data
))
def
unknown_entityref
(
self
,
data
):
self
.
add
(
EntityRef
(
data
))
def
escape
(
data
,
rmap
=
{}):
data
=
data
.
replace
(
"&"
,
"&"
)
data
=
data
.
replace
(
"<"
,
"<"
)
data
=
data
.
replace
(
">"
,
">"
)
for
key
,
val
in
rmap
.
items
():
data
=
data
.
replace
(
key
,
val
)
return
data
def
remap
(
data
,
dict
=
{
'DAV:'
:
'd'
}):
root
=
XmlParser
().
parse
(
data
)
root
.
elements
()[
0
].
remap
(
dict
,
0
)
return
root
.
toxml
()
def
parse
(
self
,
data
):
self
.
dom
=
minidom
.
parseString
(
data
)
return
Node
(
self
.
dom
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment