Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
075854fc
Kaydet (Commit)
075854fc
authored
Ara 12, 2005
tarafından
Fredrik Lundh
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
added ElementTree core components to xml.etree
üst
c5c57e6d
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1621 additions
and
0 deletions
+1621
-0
ElementInclude.py
Lib/xml/etree/ElementInclude.py
+141
-0
ElementPath.py
Lib/xml/etree/ElementPath.py
+196
-0
ElementTree.py
Lib/xml/etree/ElementTree.py
+1254
-0
__init__.py
Lib/xml/etree/__init__.py
+30
-0
No files found.
Lib/xml/etree/ElementInclude.py
0 → 100644
Dosyayı görüntüle @
075854fc
#
# ElementTree
# $Id: ElementInclude.py 1862 2004-06-18 07:31:02Z Fredrik $
#
# limited xinclude support for element trees
#
# history:
# 2003-08-15 fl created
# 2003-11-14 fl fixed default loader
#
# Copyright (c) 2003-2004 by Fredrik Lundh. All rights reserved.
#
# fredrik@pythonware.com
# http://www.pythonware.com
#
# --------------------------------------------------------------------
# The ElementTree toolkit is
#
# Copyright (c) 1999-2004 by Fredrik Lundh
#
# By obtaining, using, and/or copying this software and/or its
# associated documentation, you agree that you have read, understood,
# and will comply with the following terms and conditions:
#
# Permission to use, copy, modify, and distribute this software and
# its associated documentation for any purpose and without fee is
# hereby granted, provided that the above copyright notice appears in
# all copies, and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of
# Secret Labs AB or the author not be used in advertising or publicity
# pertaining to distribution of the software without specific, written
# prior permission.
#
# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
# --------------------------------------------------------------------
##
# Limited XInclude support for the ElementTree package.
##
import
copy
import
ElementTree
XINCLUDE
=
"{http://www.w3.org/2001/XInclude}"
XINCLUDE_INCLUDE
=
XINCLUDE
+
"include"
XINCLUDE_FALLBACK
=
XINCLUDE
+
"fallback"
##
# Fatal include error.
class
FatalIncludeError
(
SyntaxError
):
pass
##
# Default loader. This loader reads an included resource from disk.
#
# @param href Resource reference.
# @param parse Parse mode. Either "xml" or "text".
# @param encoding Optional text encoding.
# @return The expanded resource. If the parse mode is "xml", this
# is an ElementTree instance. If the parse mode is "text", this
# is a Unicode string. If the loader fails, it can return None
# or raise an IOError exception.
# @throws IOError If the loader fails to load the resource.
def
default_loader
(
href
,
parse
,
encoding
=
None
):
file
=
open
(
href
)
if
parse
==
"xml"
:
data
=
ElementTree
.
parse
(
file
)
.
getroot
()
else
:
data
=
file
.
read
()
if
encoding
:
data
=
data
.
decode
(
encoding
)
file
.
close
()
return
data
##
# Expand XInclude directives.
#
# @param elem Root element.
# @param loader Optional resource loader. If omitted, it defaults
# to {@link default_loader}. If given, it should be a callable
# that implements the same interface as <b>default_loader</b>.
# @throws FatalIncludeError If the function fails to include a given
# resource, or if the tree contains malformed XInclude elements.
# @throws IOError If the function fails to load a given resource.
def
include
(
elem
,
loader
=
None
):
if
loader
is
None
:
loader
=
default_loader
# look for xinclude elements
i
=
0
while
i
<
len
(
elem
):
e
=
elem
[
i
]
if
e
.
tag
==
XINCLUDE_INCLUDE
:
# process xinclude directive
href
=
e
.
get
(
"href"
)
parse
=
e
.
get
(
"parse"
,
"xml"
)
if
parse
==
"xml"
:
node
=
loader
(
href
,
parse
)
if
node
is
None
:
raise
FatalIncludeError
(
"cannot load
%
r as
%
r"
%
(
href
,
parse
)
)
node
=
copy
.
copy
(
node
)
if
e
.
tail
:
node
.
tail
=
(
node
.
tail
or
""
)
+
e
.
tail
elem
[
i
]
=
node
elif
parse
==
"text"
:
text
=
loader
(
href
,
parse
,
e
.
get
(
"encoding"
))
if
text
is
None
:
raise
FatalIncludeError
(
"cannot load
%
r as
%
r"
%
(
href
,
parse
)
)
if
i
:
node
=
elem
[
i
-
1
]
node
.
tail
=
(
node
.
tail
or
""
)
+
text
else
:
elem
.
text
=
(
elem
.
text
or
""
)
+
text
+
(
e
.
tail
or
""
)
del
elem
[
i
]
continue
else
:
raise
FatalIncludeError
(
"unknown parse type in xi:include tag (
%
r)"
%
parse
)
elif
e
.
tag
==
XINCLUDE_FALLBACK
:
raise
FatalIncludeError
(
"xi:fallback tag must be child of xi:include (
%
r)"
%
e
.
tag
)
else
:
include
(
e
,
loader
)
i
=
i
+
1
Lib/xml/etree/ElementPath.py
0 → 100644
Dosyayı görüntüle @
075854fc
#
# ElementTree
# $Id: ElementPath.py 1858 2004-06-17 21:31:41Z Fredrik $
#
# limited xpath support for element trees
#
# history:
# 2003-05-23 fl created
# 2003-05-28 fl added support for // etc
# 2003-08-27 fl fixed parsing of periods in element names
#
# Copyright (c) 2003-2004 by Fredrik Lundh. All rights reserved.
#
# fredrik@pythonware.com
# http://www.pythonware.com
#
# --------------------------------------------------------------------
# The ElementTree toolkit is
#
# Copyright (c) 1999-2004 by Fredrik Lundh
#
# By obtaining, using, and/or copying this software and/or its
# associated documentation, you agree that you have read, understood,
# and will comply with the following terms and conditions:
#
# Permission to use, copy, modify, and distribute this software and
# its associated documentation for any purpose and without fee is
# hereby granted, provided that the above copyright notice appears in
# all copies, and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of
# Secret Labs AB or the author not be used in advertising or publicity
# pertaining to distribution of the software without specific, written
# prior permission.
#
# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
# --------------------------------------------------------------------
##
# Implementation module for XPath support. There's usually no reason
# to import this module directly; the <b>ElementTree</b> does this for
# you, if needed.
##
import
re
xpath_tokenizer
=
re
.
compile
(
"(::|
\
.
\
.|
\
(
\
)|[/.*:
\
[
\
]
\
(
\
)@=])|((?:
\
{[^}]+
\
})?[^/:
\
[
\
]
\
(
\
)@=
\
s]+)|
\
s+"
)
.
findall
class
xpath_descendant_or_self
:
pass
##
# Wrapper for a compiled XPath.
class
Path
:
##
# Create an Path instance from an XPath expression.
def
__init__
(
self
,
path
):
tokens
=
xpath_tokenizer
(
path
)
# the current version supports 'path/path'-style expressions only
self
.
path
=
[]
self
.
tag
=
None
if
tokens
and
tokens
[
0
][
0
]
==
"/"
:
raise
SyntaxError
(
"cannot use absolute path on element"
)
while
tokens
:
op
,
tag
=
tokens
.
pop
(
0
)
if
tag
or
op
==
"*"
:
self
.
path
.
append
(
tag
or
op
)
elif
op
==
"."
:
pass
elif
op
==
"/"
:
self
.
path
.
append
(
xpath_descendant_or_self
())
continue
else
:
raise
SyntaxError
(
"unsupported path syntax (
%
s)"
%
op
)
if
tokens
:
op
,
tag
=
tokens
.
pop
(
0
)
if
op
!=
"/"
:
raise
SyntaxError
(
"expected path separator (
%
s)"
%
(
op
or
tag
)
)
if
self
.
path
and
isinstance
(
self
.
path
[
-
1
],
xpath_descendant_or_self
):
raise
SyntaxError
(
"path cannot end with //"
)
if
len
(
self
.
path
)
==
1
and
isinstance
(
self
.
path
[
0
],
type
(
""
)):
self
.
tag
=
self
.
path
[
0
]
##
# Find first matching object.
def
find
(
self
,
element
):
tag
=
self
.
tag
if
tag
is
None
:
nodeset
=
self
.
findall
(
element
)
if
not
nodeset
:
return
None
return
nodeset
[
0
]
for
elem
in
element
:
if
elem
.
tag
==
tag
:
return
elem
return
None
##
# Find text for first matching object.
def
findtext
(
self
,
element
,
default
=
None
):
tag
=
self
.
tag
if
tag
is
None
:
nodeset
=
self
.
findall
(
element
)
if
not
nodeset
:
return
default
return
nodeset
[
0
]
.
text
or
""
for
elem
in
element
:
if
elem
.
tag
==
tag
:
return
elem
.
text
or
""
return
default
##
# Find all matching objects.
def
findall
(
self
,
element
):
nodeset
=
[
element
]
index
=
0
while
1
:
try
:
path
=
self
.
path
[
index
]
index
=
index
+
1
except
IndexError
:
return
nodeset
set
=
[]
if
isinstance
(
path
,
xpath_descendant_or_self
):
try
:
tag
=
self
.
path
[
index
]
if
not
isinstance
(
tag
,
type
(
""
)):
tag
=
None
else
:
index
=
index
+
1
except
IndexError
:
tag
=
None
# invalid path
for
node
in
nodeset
:
new
=
list
(
node
.
getiterator
(
tag
))
if
new
and
new
[
0
]
is
node
:
set
.
extend
(
new
[
1
:])
else
:
set
.
extend
(
new
)
else
:
for
node
in
nodeset
:
for
node
in
node
:
if
path
==
"*"
or
node
.
tag
==
path
:
set
.
append
(
node
)
if
not
set
:
return
[]
nodeset
=
set
_cache
=
{}
##
# (Internal) Compile path.
def
_compile
(
path
):
p
=
_cache
.
get
(
path
)
if
p
is
not
None
:
return
p
p
=
Path
(
path
)
if
len
(
_cache
)
>=
100
:
_cache
.
clear
()
_cache
[
path
]
=
p
return
p
##
# Find first matching object.
def
find
(
element
,
path
):
return
_compile
(
path
)
.
find
(
element
)
##
# Find text for first matching object.
def
findtext
(
element
,
path
,
default
=
None
):
return
_compile
(
path
)
.
findtext
(
element
,
default
)
##
# Find all matching objects.
def
findall
(
element
,
path
):
return
_compile
(
path
)
.
findall
(
element
)
Lib/xml/etree/ElementTree.py
0 → 100644
Dosyayı görüntüle @
075854fc
#
# ElementTree
# $Id: ElementTree.py 2326 2005-03-17 07:45:21Z fredrik $
#
# light-weight XML support for Python 1.5.2 and later.
#
# history:
# 2001-10-20 fl created (from various sources)
# 2001-11-01 fl return root from parse method
# 2002-02-16 fl sort attributes in lexical order
# 2002-04-06 fl TreeBuilder refactoring, added PythonDoc markup
# 2002-05-01 fl finished TreeBuilder refactoring
# 2002-07-14 fl added basic namespace support to ElementTree.write
# 2002-07-25 fl added QName attribute support
# 2002-10-20 fl fixed encoding in write
# 2002-11-24 fl changed default encoding to ascii; fixed attribute encoding
# 2002-11-27 fl accept file objects or file names for parse/write
# 2002-12-04 fl moved XMLTreeBuilder back to this module
# 2003-01-11 fl fixed entity encoding glitch for us-ascii
# 2003-02-13 fl added XML literal factory
# 2003-02-21 fl added ProcessingInstruction/PI factory
# 2003-05-11 fl added tostring/fromstring helpers
# 2003-05-26 fl added ElementPath support
# 2003-07-05 fl added makeelement factory method
# 2003-07-28 fl added more well-known namespace prefixes
# 2003-08-15 fl fixed typo in ElementTree.findtext (Thomas Dartsch)
# 2003-09-04 fl fall back on emulator if ElementPath is not installed
# 2003-10-31 fl markup updates
# 2003-11-15 fl fixed nested namespace bug
# 2004-03-28 fl added XMLID helper
# 2004-06-02 fl added default support to findtext
# 2004-06-08 fl fixed encoding of non-ascii element/attribute names
# 2004-08-23 fl take advantage of post-2.1 expat features
# 2005-02-01 fl added iterparse implementation
# 2005-03-02 fl fixed iterparse support for pre-2.2 versions
#
# Copyright (c) 1999-2005 by Fredrik Lundh. All rights reserved.
#
# fredrik@pythonware.com
# http://www.pythonware.com
#
# --------------------------------------------------------------------
# The ElementTree toolkit is
#
# Copyright (c) 1999-2005 by Fredrik Lundh
#
# By obtaining, using, and/or copying this software and/or its
# associated documentation, you agree that you have read, understood,
# and will comply with the following terms and conditions:
#
# Permission to use, copy, modify, and distribute this software and
# its associated documentation for any purpose and without fee is
# hereby granted, provided that the above copyright notice appears in
# all copies, and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of
# Secret Labs AB or the author not be used in advertising or publicity
# pertaining to distribution of the software without specific, written
# prior permission.
#
# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
# --------------------------------------------------------------------
__all__
=
[
# public symbols
"Comment"
,
"dump"
,
"Element"
,
"ElementTree"
,
"fromstring"
,
"iselement"
,
"iterparse"
,
"parse"
,
"PI"
,
"ProcessingInstruction"
,
"QName"
,
"SubElement"
,
"tostring"
,
"TreeBuilder"
,
"VERSION"
,
"XML"
,
"XMLTreeBuilder"
,
]
##
# The <b>Element</b> type is a flexible container object, designed to
# store hierarchical data structures in memory. The type can be
# described as a cross between a list and a dictionary.
# <p>
# Each element has a number of properties associated with it:
# <ul>
# <li>a <i>tag</i>. This is a string identifying what kind of data
# this element represents (the element type, in other words).</li>
# <li>a number of <i>attributes</i>, stored in a Python dictionary.</li>
# <li>a <i>text</i> string.</li>
# <li>an optional <i>tail</i> string.</li>
# <li>a number of <i>child elements</i>, stored in a Python sequence</li>
# </ul>
#
# To create an element instance, use the {@link #Element} or {@link
# #SubElement} factory functions.
# <p>
# The {@link #ElementTree} class can be used to wrap an element
# structure, and convert it from and to XML.
##
import
string
,
sys
,
re
class
_SimpleElementPath
:
# emulate pre-1.2 find/findtext/findall behaviour
def
find
(
self
,
element
,
tag
):
for
elem
in
element
:
if
elem
.
tag
==
tag
:
return
elem
return
None
def
findtext
(
self
,
element
,
tag
,
default
=
None
):
for
elem
in
element
:
if
elem
.
tag
==
tag
:
return
elem
.
text
or
""
return
default
def
findall
(
self
,
element
,
tag
):
if
tag
[:
3
]
==
".//"
:
return
element
.
getiterator
(
tag
[
3
:])
result
=
[]
for
elem
in
element
:
if
elem
.
tag
==
tag
:
result
.
append
(
elem
)
return
result
try
:
import
ElementPath
except
ImportError
:
# FIXME: issue warning in this case?
ElementPath
=
_SimpleElementPath
()
# TODO: add support for custom namespace resolvers/default namespaces
# TODO: add improved support for incremental parsing
VERSION
=
"1.2.6"
##
# Internal element class. This class defines the Element interface,
# and provides a reference implementation of this interface.
# <p>
# You should not create instances of this class directly. Use the
# appropriate factory functions instead, such as {@link #Element}
# and {@link #SubElement}.
#
# @see Element
# @see SubElement
# @see Comment
# @see ProcessingInstruction
class
_ElementInterface
:
# <tag attrib>text<child/>...</tag>tail
##
# (Attribute) Element tag.
tag
=
None
##
# (Attribute) Element attribute dictionary. Where possible, use
# {@link #_ElementInterface.get},
# {@link #_ElementInterface.set},
# {@link #_ElementInterface.keys}, and
# {@link #_ElementInterface.items} to access
# element attributes.
attrib
=
None
##
# (Attribute) Text before first subelement. This is either a
# string or the value None, if there was no text.
text
=
None
##
# (Attribute) Text after this element's end tag, but before the
# next sibling element's start tag. This is either a string or
# the value None, if there was no text.
tail
=
None
# text after end tag, if any
def
__init__
(
self
,
tag
,
attrib
):
self
.
tag
=
tag
self
.
attrib
=
attrib
self
.
_children
=
[]
def
__repr__
(
self
):
return
"<Element
%
s at
%
x>"
%
(
self
.
tag
,
id
(
self
))
##
# Creates a new element object of the same type as this element.
#
# @param tag Element tag.
# @param attrib Element attributes, given as a dictionary.
# @return A new element instance.
def
makeelement
(
self
,
tag
,
attrib
):
return
Element
(
tag
,
attrib
)
##
# Returns the number of subelements.
#
# @return The number of subelements.
def
__len__
(
self
):
return
len
(
self
.
_children
)
##
# Returns the given subelement.
#
# @param index What subelement to return.
# @return The given subelement.
# @exception IndexError If the given element does not exist.
def
__getitem__
(
self
,
index
):
return
self
.
_children
[
index
]
##
# Replaces the given subelement.
#
# @param index What subelement to replace.
# @param element The new element value.
# @exception IndexError If the given element does not exist.
# @exception AssertionError If element is not a valid object.
def
__setitem__
(
self
,
index
,
element
):
assert
iselement
(
element
)
self
.
_children
[
index
]
=
element
##
# Deletes the given subelement.
#
# @param index What subelement to delete.
# @exception IndexError If the given element does not exist.
def
__delitem__
(
self
,
index
):
del
self
.
_children
[
index
]
##
# Returns a list containing subelements in the given range.
#
# @param start The first subelement to return.
# @param stop The first subelement that shouldn't be returned.
# @return A sequence object containing subelements.
def
__getslice__
(
self
,
start
,
stop
):
return
self
.
_children
[
start
:
stop
]
##
# Replaces a number of subelements with elements from a sequence.
#
# @param start The first subelement to replace.
# @param stop The first subelement that shouldn't be replaced.
# @param elements A sequence object with zero or more elements.
# @exception AssertionError If a sequence member is not a valid object.
def
__setslice__
(
self
,
start
,
stop
,
elements
):
for
element
in
elements
:
assert
iselement
(
element
)
self
.
_children
[
start
:
stop
]
=
list
(
elements
)
##
# Deletes a number of subelements.
#
# @param start The first subelement to delete.
# @param stop The first subelement to leave in there.
def
__delslice__
(
self
,
start
,
stop
):
del
self
.
_children
[
start
:
stop
]
##
# Adds a subelement to the end of this element.
#
# @param element The element to add.
# @exception AssertionError If a sequence member is not a valid object.
def
append
(
self
,
element
):
assert
iselement
(
element
)
self
.
_children
.
append
(
element
)
##
# Inserts a subelement at the given position in this element.
#
# @param index Where to insert the new subelement.
# @exception AssertionError If the element is not a valid object.
def
insert
(
self
,
index
,
element
):
assert
iselement
(
element
)
self
.
_children
.
insert
(
index
,
element
)
##
# Removes a matching subelement. Unlike the <b>find</b> methods,
# this method compares elements based on identity, not on tag
# value or contents.
#
# @param element What element to remove.
# @exception ValueError If a matching element could not be found.
# @exception AssertionError If the element is not a valid object.
def
remove
(
self
,
element
):
assert
iselement
(
element
)
self
.
_children
.
remove
(
element
)
##
# Returns all subelements. The elements are returned in document
# order.
#
# @return A list of subelements.
# @defreturn list of Element instances
def
getchildren
(
self
):
return
self
.
_children
##
# Finds the first matching subelement, by tag name or path.
#
# @param path What element to look for.
# @return The first matching element, or None if no element was found.
# @defreturn Element or None
def
find
(
self
,
path
):
return
ElementPath
.
find
(
self
,
path
)
##
# Finds text for the first matching subelement, by tag name or path.
#
# @param path What element to look for.
# @param default What to return if the element was not found.
# @return The text content of the first matching element, or the
# default value no element was found. Note that if the element
# has is found, but has no text content, this method returns an
# empty string.
# @defreturn string
def
findtext
(
self
,
path
,
default
=
None
):
return
ElementPath
.
findtext
(
self
,
path
,
default
)
##
# Finds all matching subelements, by tag name or path.
#
# @param path What element to look for.
# @return A list or iterator containing all matching elements,
# in document order.
# @defreturn list of Element instances
def
findall
(
self
,
path
):
return
ElementPath
.
findall
(
self
,
path
)
##
# Resets an element. This function removes all subelements, clears
# all attributes, and sets the text and tail attributes to None.
def
clear
(
self
):
self
.
attrib
.
clear
()
self
.
_children
=
[]
self
.
text
=
self
.
tail
=
None
##
# Gets an element attribute.
#
# @param key What attribute to look for.
# @param default What to return if the attribute was not found.
# @return The attribute value, or the default value, if the
# attribute was not found.
# @defreturn string or None
def
get
(
self
,
key
,
default
=
None
):
return
self
.
attrib
.
get
(
key
,
default
)
##
# Sets an element attribute.
#
# @param key What attribute to set.
# @param value The attribute value.
def
set
(
self
,
key
,
value
):
self
.
attrib
[
key
]
=
value
##
# Gets a list of attribute names. The names are returned in an
# arbitrary order (just like for an ordinary Python dictionary).
#
# @return A list of element attribute names.
# @defreturn list of strings
def
keys
(
self
):
return
self
.
attrib
.
keys
()
##
# Gets element attributes, as a sequence. The attributes are
# returned in an arbitrary order.
#
# @return A list of (name, value) tuples for all attributes.
# @defreturn list of (string, string) tuples
def
items
(
self
):
return
self
.
attrib
.
items
()
##
# Creates a tree iterator. The iterator loops over this element
# and all subelements, in document order, and returns all elements
# with a matching tag.
# <p>
# If the tree structure is modified during iteration, the result
# is undefined.
#
# @param tag What tags to look for (default is to return all elements).
# @return A list or iterator containing all the matching elements.
# @defreturn list or iterator
def
getiterator
(
self
,
tag
=
None
):
nodes
=
[]
if
tag
==
"*"
:
tag
=
None
if
tag
is
None
or
self
.
tag
==
tag
:
nodes
.
append
(
self
)
for
node
in
self
.
_children
:
nodes
.
extend
(
node
.
getiterator
(
tag
))
return
nodes
# compatibility
_Element
=
_ElementInterface
##
# Element factory. This function returns an object implementing the
# standard Element interface. The exact class or type of that object
# is implementation dependent, but it will always be compatible with
# the {@link #_ElementInterface} class in this module.
# <p>
# The element name, attribute names, and attribute values can be
# either 8-bit ASCII strings or Unicode strings.
#
# @param tag The element name.
# @param attrib An optional dictionary, containing element attributes.
# @param **extra Additional attributes, given as keyword arguments.
# @return An element instance.
# @defreturn Element
def
Element
(
tag
,
attrib
=
{},
**
extra
):
attrib
=
attrib
.
copy
()
attrib
.
update
(
extra
)
return
_ElementInterface
(
tag
,
attrib
)
##
# Subelement factory. This function creates an element instance, and
# appends it to an existing element.
# <p>
# The element name, attribute names, and attribute values can be
# either 8-bit ASCII strings or Unicode strings.
#
# @param parent The parent element.
# @param tag The subelement name.
# @param attrib An optional dictionary, containing element attributes.
# @param **extra Additional attributes, given as keyword arguments.
# @return An element instance.
# @defreturn Element
def
SubElement
(
parent
,
tag
,
attrib
=
{},
**
extra
):
attrib
=
attrib
.
copy
()
attrib
.
update
(
extra
)
element
=
parent
.
makeelement
(
tag
,
attrib
)
parent
.
append
(
element
)
return
element
##
# Comment element factory. This factory function creates a special
# element that will be serialized as an XML comment.
# <p>
# The comment string can be either an 8-bit ASCII string or a Unicode
# string.
#
# @param text A string containing the comment string.
# @return An element instance, representing a comment.
# @defreturn Element
def
Comment
(
text
=
None
):
element
=
Element
(
Comment
)
element
.
text
=
text
return
element
##
# PI element factory. This factory function creates a special element
# that will be serialized as an XML processing instruction.
#
# @param target A string containing the PI target.
# @param text A string containing the PI contents, if any.
# @return An element instance, representing a PI.
# @defreturn Element
def
ProcessingInstruction
(
target
,
text
=
None
):
element
=
Element
(
ProcessingInstruction
)
element
.
text
=
target
if
text
:
element
.
text
=
element
.
text
+
" "
+
text
return
element
PI
=
ProcessingInstruction
##
# QName wrapper. This can be used to wrap a QName attribute value, in
# order to get proper namespace handling on output.
#
# @param text A string containing the QName value, in the form {uri}local,
# or, if the tag argument is given, the URI part of a QName.
# @param tag Optional tag. If given, the first argument is interpreted as
# an URI, and this argument is interpreted as a local name.
# @return An opaque object, representing the QName.
class
QName
:
def
__init__
(
self
,
text_or_uri
,
tag
=
None
):
if
tag
:
text_or_uri
=
"{
%
s}
%
s"
%
(
text_or_uri
,
tag
)
self
.
text
=
text_or_uri
def
__str__
(
self
):
return
self
.
text
def
__hash__
(
self
):
return
hash
(
self
.
text
)
def
__cmp__
(
self
,
other
):
if
isinstance
(
other
,
QName
):
return
cmp
(
self
.
text
,
other
.
text
)
return
cmp
(
self
.
text
,
other
)
##
# ElementTree wrapper class. This class represents an entire element
# hierarchy, and adds some extra support for serialization to and from
# standard XML.
#
# @param element Optional root element.
# @keyparam file Optional file handle or name. If given, the
# tree is initialized with the contents of this XML file.
class
ElementTree
:
def
__init__
(
self
,
element
=
None
,
file
=
None
):
assert
element
is
None
or
iselement
(
element
)
self
.
_root
=
element
# first node
if
file
:
self
.
parse
(
file
)
##
# Gets the root element for this tree.
#
# @return An element instance.
# @defreturn Element
def
getroot
(
self
):
return
self
.
_root
##
# Replaces the root element for this tree. This discards the
# current contents of the tree, and replaces it with the given
# element. Use with care.
#
# @param element An element instance.
def
_setroot
(
self
,
element
):
assert
iselement
(
element
)
self
.
_root
=
element
##
# Loads an external XML document into this element tree.
#
# @param source A file name or file object.
# @param parser An optional parser instance. If not given, the
# standard {@link XMLTreeBuilder} parser is used.
# @return The document root element.
# @defreturn Element
def
parse
(
self
,
source
,
parser
=
None
):
if
not
hasattr
(
source
,
"read"
):
source
=
open
(
source
,
"rb"
)
if
not
parser
:
parser
=
XMLTreeBuilder
()
while
1
:
data
=
source
.
read
(
32768
)
if
not
data
:
break
parser
.
feed
(
data
)
self
.
_root
=
parser
.
close
()
return
self
.
_root
##
# Creates a tree iterator for the root element. The iterator loops
# over all elements in this tree, in document order.
#
# @param tag What tags to look for (default is to return all elements)
# @return An iterator.
# @defreturn iterator
def
getiterator
(
self
,
tag
=
None
):
assert
self
.
_root
is
not
None
return
self
.
_root
.
getiterator
(
tag
)
##
# Finds the first toplevel element with given tag.
# Same as getroot().find(path).
#
# @param path What element to look for.
# @return The first matching element, or None if no element was found.
# @defreturn Element or None
def
find
(
self
,
path
):
assert
self
.
_root
is
not
None
if
path
[:
1
]
==
"/"
:
path
=
"."
+
path
return
self
.
_root
.
find
(
path
)
##
# Finds the element text for the first toplevel element with given
# tag. Same as getroot().findtext(path).
#
# @param path What toplevel element to look for.
# @param default What to return if the element was not found.
# @return The text content of the first matching element, or the
# default value no element was found. Note that if the element
# has is found, but has no text content, this method returns an
# empty string.
# @defreturn string
def
findtext
(
self
,
path
,
default
=
None
):
assert
self
.
_root
is
not
None
if
path
[:
1
]
==
"/"
:
path
=
"."
+
path
return
self
.
_root
.
findtext
(
path
,
default
)
##
# Finds all toplevel elements with the given tag.
# Same as getroot().findall(path).
#
# @param path What element to look for.
# @return A list or iterator containing all matching elements,
# in document order.
# @defreturn list of Element instances
def
findall
(
self
,
path
):
assert
self
.
_root
is
not
None
if
path
[:
1
]
==
"/"
:
path
=
"."
+
path
return
self
.
_root
.
findall
(
path
)
##
# Writes the element tree to a file, as XML.
#
# @param file A file name, or a file object opened for writing.
# @param encoding Optional output encoding (default is US-ASCII).
def
write
(
self
,
file
,
encoding
=
"us-ascii"
):
assert
self
.
_root
is
not
None
if
not
hasattr
(
file
,
"write"
):
file
=
open
(
file
,
"wb"
)
if
not
encoding
:
encoding
=
"us-ascii"
elif
encoding
!=
"utf-8"
and
encoding
!=
"us-ascii"
:
file
.
write
(
"<?xml version='1.0' encoding='
%
s'?>
\n
"
%
encoding
)
self
.
_write
(
file
,
self
.
_root
,
encoding
,
{})
def
_write
(
self
,
file
,
node
,
encoding
,
namespaces
):
# write XML to file
tag
=
node
.
tag
if
tag
is
Comment
:
file
.
write
(
"<!--
%
s -->"
%
_escape_cdata
(
node
.
text
,
encoding
))
elif
tag
is
ProcessingInstruction
:
file
.
write
(
"<?
%
s?>"
%
_escape_cdata
(
node
.
text
,
encoding
))
else
:
items
=
node
.
items
()
xmlns_items
=
[]
# new namespaces in this scope
try
:
if
isinstance
(
tag
,
QName
)
or
tag
[:
1
]
==
"{"
:
tag
,
xmlns
=
fixtag
(
tag
,
namespaces
)
if
xmlns
:
xmlns_items
.
append
(
xmlns
)
except
TypeError
:
_raise_serialization_error
(
tag
)
file
.
write
(
"<"
+
_encode
(
tag
,
encoding
))
if
items
or
xmlns_items
:
items
.
sort
()
# lexical order
for
k
,
v
in
items
:
try
:
if
isinstance
(
k
,
QName
)
or
k
[:
1
]
==
"{"
:
k
,
xmlns
=
fixtag
(
k
,
namespaces
)
if
xmlns
:
xmlns_items
.
append
(
xmlns
)
except
TypeError
:
_raise_serialization_error
(
k
)
try
:
if
isinstance
(
v
,
QName
):
v
,
xmlns
=
fixtag
(
v
,
namespaces
)
if
xmlns
:
xmlns_items
.
append
(
xmlns
)
except
TypeError
:
_raise_serialization_error
(
v
)
file
.
write
(
"
%
s=
\"
%
s
\"
"
%
(
_encode
(
k
,
encoding
),
_escape_attrib
(
v
,
encoding
)))
for
k
,
v
in
xmlns_items
:
file
.
write
(
"
%
s=
\"
%
s
\"
"
%
(
_encode
(
k
,
encoding
),
_escape_attrib
(
v
,
encoding
)))
if
node
.
text
or
len
(
node
):
file
.
write
(
">"
)
if
node
.
text
:
file
.
write
(
_escape_cdata
(
node
.
text
,
encoding
))
for
n
in
node
:
self
.
_write
(
file
,
n
,
encoding
,
namespaces
)
file
.
write
(
"</"
+
_encode
(
tag
,
encoding
)
+
">"
)
else
:
file
.
write
(
" />"
)
for
k
,
v
in
xmlns_items
:
del
namespaces
[
v
]
if
node
.
tail
:
file
.
write
(
_escape_cdata
(
node
.
tail
,
encoding
))
# --------------------------------------------------------------------
# helpers
##
# Checks if an object appears to be a valid element object.
#
# @param An element instance.
# @return A true value if this is an element object.
# @defreturn flag
def
iselement
(
element
):
# FIXME: not sure about this; might be a better idea to look
# for tag/attrib/text attributes
return
isinstance
(
element
,
_ElementInterface
)
or
hasattr
(
element
,
"tag"
)
##
# Writes an element tree or element structure to sys.stdout. This
# function should be used for debugging only.
# <p>
# The exact output format is implementation dependent. In this
# version, it's written as an ordinary XML file.
#
# @param elem An element tree or an individual element.
def
dump
(
elem
):
# debugging
if
not
isinstance
(
elem
,
ElementTree
):
elem
=
ElementTree
(
elem
)
elem
.
write
(
sys
.
stdout
)
tail
=
elem
.
getroot
()
.
tail
if
not
tail
or
tail
[
-
1
]
!=
"
\n
"
:
sys
.
stdout
.
write
(
"
\n
"
)
def
_encode
(
s
,
encoding
):
try
:
return
s
.
encode
(
encoding
)
except
AttributeError
:
return
s
# 1.5.2: assume the string uses the right encoding
if
sys
.
version
[:
3
]
==
"1.5"
:
_escape
=
re
.
compile
(
r"[&<>\"\x80-\xff]+"
)
# 1.5.2
else
:
_escape
=
re
.
compile
(
eval
(
r'u"[&<>\"\u0080-\uffff]+"'
))
_escape_map
=
{
"&"
:
"&"
,
"<"
:
"<"
,
">"
:
">"
,
'"'
:
"""
,
}
_namespace_map
=
{
# "well-known" namespace prefixes
"http://www.w3.org/XML/1998/namespace"
:
"xml"
,
"http://www.w3.org/1999/xhtml"
:
"html"
,
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
:
"rdf"
,
"http://schemas.xmlsoap.org/wsdl/"
:
"wsdl"
,
}
def
_raise_serialization_error
(
text
):
raise
TypeError
(
"cannot serialize
%
r (type
%
s)"
%
(
text
,
type
(
text
)
.
__name__
)
)
def
_encode_entity
(
text
,
pattern
=
_escape
):
# map reserved and non-ascii characters to numerical entities
def
escape_entities
(
m
,
map
=
_escape_map
):
out
=
[]
append
=
out
.
append
for
char
in
m
.
group
():
text
=
map
.
get
(
char
)
if
text
is
None
:
text
=
"&#
%
d;"
%
ord
(
char
)
append
(
text
)
return
string
.
join
(
out
,
""
)
try
:
return
_encode
(
pattern
.
sub
(
escape_entities
,
text
),
"ascii"
)
except
TypeError
:
_raise_serialization_error
(
text
)
#
# the following functions assume an ascii-compatible encoding
# (or "utf-16")
def
_escape_cdata
(
text
,
encoding
=
None
,
replace
=
string
.
replace
):
# escape character data
try
:
if
encoding
:
try
:
text
=
_encode
(
text
,
encoding
)
except
UnicodeError
:
return
_encode_entity
(
text
)
text
=
replace
(
text
,
"&"
,
"&"
)
text
=
replace
(
text
,
"<"
,
"<"
)
text
=
replace
(
text
,
">"
,
">"
)
return
text
except
(
TypeError
,
AttributeError
):
_raise_serialization_error
(
text
)
def
_escape_attrib
(
text
,
encoding
=
None
,
replace
=
string
.
replace
):
# escape attribute value
try
:
if
encoding
:
try
:
text
=
_encode
(
text
,
encoding
)
except
UnicodeError
:
return
_encode_entity
(
text
)
text
=
replace
(
text
,
"&"
,
"&"
)
text
=
replace
(
text
,
"'"
,
"'"
)
# FIXME: overkill
text
=
replace
(
text
,
"
\"
"
,
"""
)
text
=
replace
(
text
,
"<"
,
"<"
)
text
=
replace
(
text
,
">"
,
">"
)
return
text
except
(
TypeError
,
AttributeError
):
_raise_serialization_error
(
text
)
def
fixtag
(
tag
,
namespaces
):
# given a decorated tag (of the form {uri}tag), return prefixed
# tag and namespace declaration, if any
if
isinstance
(
tag
,
QName
):
tag
=
tag
.
text
namespace_uri
,
tag
=
string
.
split
(
tag
[
1
:],
"}"
,
1
)
prefix
=
namespaces
.
get
(
namespace_uri
)
if
prefix
is
None
:
prefix
=
_namespace_map
.
get
(
namespace_uri
)
if
prefix
is
None
:
prefix
=
"ns
%
d"
%
len
(
namespaces
)
namespaces
[
namespace_uri
]
=
prefix
if
prefix
==
"xml"
:
xmlns
=
None
else
:
xmlns
=
(
"xmlns:
%
s"
%
prefix
,
namespace_uri
)
else
:
xmlns
=
None
return
"
%
s:
%
s"
%
(
prefix
,
tag
),
xmlns
##
# Parses an XML document into an element tree.
#
# @param source A filename or file object containing XML data.
# @param parser An optional parser instance. If not given, the
# standard {@link XMLTreeBuilder} parser is used.
# @return An ElementTree instance
def
parse
(
source
,
parser
=
None
):
tree
=
ElementTree
()
tree
.
parse
(
source
,
parser
)
return
tree
##
# Parses an XML document into an element tree incrementally, and reports
# what's going on to the user.
#
# @param source A filename or file object containing XML data.
# @param events A list of events to report back. If omitted, only "end"
# events are reported.
# @return A (event, elem) iterator.
class
iterparse
:
def
__init__
(
self
,
source
,
events
=
None
):
if
not
hasattr
(
source
,
"read"
):
source
=
open
(
source
,
"rb"
)
self
.
_file
=
source
self
.
_events
=
[]
self
.
_index
=
0
self
.
root
=
self
.
_root
=
None
self
.
_parser
=
XMLTreeBuilder
()
# wire up the parser for event reporting
parser
=
self
.
_parser
.
_parser
append
=
self
.
_events
.
append
if
events
is
None
:
events
=
[
"end"
]
for
event
in
events
:
if
event
==
"start"
:
try
:
parser
.
ordered_attributes
=
1
parser
.
specified_attributes
=
1
def
handler
(
tag
,
attrib_in
,
event
=
event
,
append
=
append
,
start
=
self
.
_parser
.
_start_list
):
append
((
event
,
start
(
tag
,
attrib_in
)))
parser
.
StartElementHandler
=
handler
except
AttributeError
:
def
handler
(
tag
,
attrib_in
,
event
=
event
,
append
=
append
,
start
=
self
.
_parser
.
_start
):
append
((
event
,
start
(
tag
,
attrib_in
)))
parser
.
StartElementHandler
=
handler
elif
event
==
"end"
:
def
handler
(
tag
,
event
=
event
,
append
=
append
,
end
=
self
.
_parser
.
_end
):
append
((
event
,
end
(
tag
)))
parser
.
EndElementHandler
=
handler
elif
event
==
"start-ns"
:
def
handler
(
prefix
,
uri
,
event
=
event
,
append
=
append
):
try
:
uri
=
_encode
(
uri
,
"ascii"
)
except
UnicodeError
:
pass
append
((
event
,
(
prefix
or
""
,
uri
)))
parser
.
StartNamespaceDeclHandler
=
handler
elif
event
==
"end-ns"
:
def
handler
(
prefix
,
event
=
event
,
append
=
append
):
append
((
event
,
None
))
parser
.
EndNamespaceDeclHandler
=
handler
def
next
(
self
):
while
1
:
try
:
item
=
self
.
_events
[
self
.
_index
]
except
IndexError
:
if
self
.
_parser
is
None
:
self
.
root
=
self
.
_root
try
:
raise
StopIteration
except
NameError
:
raise
IndexError
# load event buffer
del
self
.
_events
[:]
self
.
_index
=
0
data
=
self
.
_file
.
read
(
16384
)
if
data
:
self
.
_parser
.
feed
(
data
)
else
:
self
.
_root
=
self
.
_parser
.
close
()
self
.
_parser
=
None
else
:
self
.
_index
=
self
.
_index
+
1
return
item
try
:
iter
def
__iter__
(
self
):
return
self
except
NameError
:
def
__getitem__
(
self
,
index
):
return
self
.
next
()
##
# Parses an XML document from a string constant. This function can
# be used to embed "XML literals" in Python code.
#
# @param source A string containing XML data.
# @return An Element instance.
# @defreturn Element
def
XML
(
text
):
parser
=
XMLTreeBuilder
()
parser
.
feed
(
text
)
return
parser
.
close
()
##
# Parses an XML document from a string constant, and also returns
# a dictionary which maps from element id:s to elements.
#
# @param source A string containing XML data.
# @return A tuple containing an Element instance and a dictionary.
# @defreturn (Element, dictionary)
def
XMLID
(
text
):
parser
=
XMLTreeBuilder
()
parser
.
feed
(
text
)
tree
=
parser
.
close
()
ids
=
{}
for
elem
in
tree
.
getiterator
():
id
=
elem
.
get
(
"id"
)
if
id
:
ids
[
id
]
=
elem
return
tree
,
ids
##
# Parses an XML document from a string constant. Same as {@link #XML}.
#
# @def fromstring(text)
# @param source A string containing XML data.
# @return An Element instance.
# @defreturn Element
fromstring
=
XML
##
# Generates a string representation of an XML element, including all
# subelements.
#
# @param element An Element instance.
# @return An encoded string containing the XML data.
# @defreturn string
def
tostring
(
element
,
encoding
=
None
):
class
dummy
:
pass
data
=
[]
file
=
dummy
()
file
.
write
=
data
.
append
ElementTree
(
element
)
.
write
(
file
,
encoding
)
return
string
.
join
(
data
,
""
)
##
# Generic element structure builder. This builder converts a sequence
# of {@link #TreeBuilder.start}, {@link #TreeBuilder.data}, and {@link
# #TreeBuilder.end} method calls to a well-formed element structure.
# <p>
# You can use this class to build an element structure using a custom XML
# parser, or a parser for some other XML-like format.
#
# @param element_factory Optional element factory. This factory
# is called to create new Element instances, as necessary.
class
TreeBuilder
:
def
__init__
(
self
,
element_factory
=
None
):
self
.
_data
=
[]
# data collector
self
.
_elem
=
[]
# element stack
self
.
_last
=
None
# last element
self
.
_tail
=
None
# true if we're after an end tag
if
element_factory
is
None
:
element_factory
=
_ElementInterface
self
.
_factory
=
element_factory
##
# Flushes the parser buffers, and returns the toplevel documen
# element.
#
# @return An Element instance.
# @defreturn Element
def
close
(
self
):
assert
len
(
self
.
_elem
)
==
0
,
"missing end tags"
assert
self
.
_last
!=
None
,
"missing toplevel element"
return
self
.
_last
def
_flush
(
self
):
if
self
.
_data
:
if
self
.
_last
is
not
None
:
text
=
string
.
join
(
self
.
_data
,
""
)
if
self
.
_tail
:
assert
self
.
_last
.
tail
is
None
,
"internal error (tail)"
self
.
_last
.
tail
=
text
else
:
assert
self
.
_last
.
text
is
None
,
"internal error (text)"
self
.
_last
.
text
=
text
self
.
_data
=
[]
##
# Adds text to the current element.
#
# @param data A string. This should be either an 8-bit string
# containing ASCII text, or a Unicode string.
def
data
(
self
,
data
):
self
.
_data
.
append
(
data
)
##
# Opens a new element.
#
# @param tag The element name.
# @param attrib A dictionary containing element attributes.
# @return The opened element.
# @defreturn Element
def
start
(
self
,
tag
,
attrs
):
self
.
_flush
()
self
.
_last
=
elem
=
self
.
_factory
(
tag
,
attrs
)
if
self
.
_elem
:
self
.
_elem
[
-
1
]
.
append
(
elem
)
self
.
_elem
.
append
(
elem
)
self
.
_tail
=
0
return
elem
##
# Closes the current element.
#
# @param tag The element name.
# @return The closed element.
# @defreturn Element
def
end
(
self
,
tag
):
self
.
_flush
()
self
.
_last
=
self
.
_elem
.
pop
()
assert
self
.
_last
.
tag
==
tag
,
\
"end tag mismatch (expected
%
s, got
%
s)"
%
(
self
.
_last
.
tag
,
tag
)
self
.
_tail
=
1
return
self
.
_last
##
# Element structure builder for XML source data, based on the
# <b>expat</b> parser.
#
# @keyparam target Target object. If omitted, the builder uses an
# instance of the standard {@link #TreeBuilder} class.
# @keyparam html Predefine HTML entities. This flag is not supported
# by the current implementation.
# @see #ElementTree
# @see #TreeBuilder
class
XMLTreeBuilder
:
def
__init__
(
self
,
html
=
0
,
target
=
None
):
try
:
from
xml.parsers
import
expat
except
ImportError
:
raise
ImportError
(
"No module named expat; use SimpleXMLTreeBuilder instead"
)
self
.
_parser
=
parser
=
expat
.
ParserCreate
(
None
,
"}"
)
if
target
is
None
:
target
=
TreeBuilder
()
self
.
_target
=
target
self
.
_names
=
{}
# name memo cache
# callbacks
parser
.
DefaultHandlerExpand
=
self
.
_default
parser
.
StartElementHandler
=
self
.
_start
parser
.
EndElementHandler
=
self
.
_end
parser
.
CharacterDataHandler
=
self
.
_data
# let expat do the buffering, if supported
try
:
self
.
_parser
.
buffer_text
=
1
except
AttributeError
:
pass
# use new-style attribute handling, if supported
try
:
self
.
_parser
.
ordered_attributes
=
1
self
.
_parser
.
specified_attributes
=
1
parser
.
StartElementHandler
=
self
.
_start_list
except
AttributeError
:
pass
encoding
=
None
if
not
parser
.
returns_unicode
:
encoding
=
"utf-8"
# target.xml(encoding, None)
self
.
_doctype
=
None
self
.
entity
=
{}
def
_fixtext
(
self
,
text
):
# convert text string to ascii, if possible
try
:
return
_encode
(
text
,
"ascii"
)
except
UnicodeError
:
return
text
def
_fixname
(
self
,
key
):
# expand qname, and convert name string to ascii, if possible
try
:
name
=
self
.
_names
[
key
]
except
KeyError
:
name
=
key
if
"}"
in
name
:
name
=
"{"
+
name
self
.
_names
[
key
]
=
name
=
self
.
_fixtext
(
name
)
return
name
def
_start
(
self
,
tag
,
attrib_in
):
fixname
=
self
.
_fixname
tag
=
fixname
(
tag
)
attrib
=
{}
for
key
,
value
in
attrib_in
.
items
():
attrib
[
fixname
(
key
)]
=
self
.
_fixtext
(
value
)
return
self
.
_target
.
start
(
tag
,
attrib
)
def
_start_list
(
self
,
tag
,
attrib_in
):
fixname
=
self
.
_fixname
tag
=
fixname
(
tag
)
attrib
=
{}
if
attrib_in
:
for
i
in
range
(
0
,
len
(
attrib_in
),
2
):
attrib
[
fixname
(
attrib_in
[
i
])]
=
self
.
_fixtext
(
attrib_in
[
i
+
1
])
return
self
.
_target
.
start
(
tag
,
attrib
)
def
_data
(
self
,
text
):
return
self
.
_target
.
data
(
self
.
_fixtext
(
text
))
def
_end
(
self
,
tag
):
return
self
.
_target
.
end
(
self
.
_fixname
(
tag
))
def
_default
(
self
,
text
):
prefix
=
text
[:
1
]
if
prefix
==
"&"
:
# deal with undefined entities
try
:
self
.
_target
.
data
(
self
.
entity
[
text
[
1
:
-
1
]])
except
KeyError
:
from
xml.parsers
import
expat
raise
expat
.
error
(
"undefined entity
%
s: line
%
d, column
%
d"
%
(
text
,
self
.
_parser
.
ErrorLineNumber
,
self
.
_parser
.
ErrorColumnNumber
)
)
elif
prefix
==
"<"
and
text
[:
9
]
==
"<!DOCTYPE"
:
self
.
_doctype
=
[]
# inside a doctype declaration
elif
self
.
_doctype
is
not
None
:
# parse doctype contents
if
prefix
==
">"
:
self
.
_doctype
=
None
return
text
=
string
.
strip
(
text
)
if
not
text
:
return
self
.
_doctype
.
append
(
text
)
n
=
len
(
self
.
_doctype
)
if
n
>
2
:
type
=
self
.
_doctype
[
1
]
if
type
==
"PUBLIC"
and
n
==
4
:
name
,
type
,
pubid
,
system
=
self
.
_doctype
elif
type
==
"SYSTEM"
and
n
==
3
:
name
,
type
,
system
=
self
.
_doctype
pubid
=
None
else
:
return
if
pubid
:
pubid
=
pubid
[
1
:
-
1
]
self
.
doctype
(
name
,
pubid
,
system
[
1
:
-
1
])
self
.
_doctype
=
None
##
# Handles a doctype declaration.
#
# @param name Doctype name.
# @param pubid Public identifier.
# @param system System identifier.
def
doctype
(
self
,
name
,
pubid
,
system
):
pass
##
# Feeds data to the parser.
#
# @param data Encoded data.
def
feed
(
self
,
data
):
self
.
_parser
.
Parse
(
data
,
0
)
##
# Finishes feeding data to the parser.
#
# @return An element structure.
# @defreturn Element
def
close
(
self
):
self
.
_parser
.
Parse
(
""
,
1
)
# end of data
tree
=
self
.
_target
.
close
()
del
self
.
_target
,
self
.
_parser
# get rid of circular references
return
tree
Lib/xml/etree/__init__.py
0 → 100644
Dosyayı görüntüle @
075854fc
# $Id: __init__.py 1821 2004-06-03 16:57:49Z fredrik $
# elementtree package
# --------------------------------------------------------------------
# The ElementTree toolkit is
#
# Copyright (c) 1999-2004 by Fredrik Lundh
#
# By obtaining, using, and/or copying this software and/or its
# associated documentation, you agree that you have read, understood,
# and will comply with the following terms and conditions:
#
# Permission to use, copy, modify, and distribute this software and
# its associated documentation for any purpose and without fee is
# hereby granted, provided that the above copyright notice appears in
# all copies, and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of
# Secret Labs AB or the author not be used in advertising or publicity
# pertaining to distribution of the software without specific, written
# prior permission.
#
# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
# --------------------------------------------------------------------
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