SimpleXMLTreeBuilder.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #
  2. # ElementTree
  3. # $Id: SimpleXMLTreeBuilder.py 1862 2004-06-18 07:31:02Z Fredrik $
  4. #
  5. # A simple XML tree builder, based on Python's xmllib
  6. #
  7. # Note that due to bugs in xmllib, this builder does not fully support
  8. # namespaces (unqualified attributes are put in the default namespace,
  9. # instead of being left as is). Run this module as a script to find
  10. # out if this affects your Python version.
  11. #
  12. # history:
  13. # 2001-10-20 fl created
  14. # 2002-05-01 fl added namespace support for xmllib
  15. # 2002-08-17 fl added xmllib sanity test
  16. #
  17. # Copyright (c) 1999-2004 by Fredrik Lundh. All rights reserved.
  18. #
  19. # fredrik@pythonware.com
  20. # http://www.pythonware.com
  21. #
  22. # --------------------------------------------------------------------
  23. # The ElementTree toolkit is
  24. #
  25. # Copyright (c) 1999-2004 by Fredrik Lundh
  26. #
  27. # By obtaining, using, and/or copying this software and/or its
  28. # associated documentation, you agree that you have read, understood,
  29. # and will comply with the following terms and conditions:
  30. #
  31. # Permission to use, copy, modify, and distribute this software and
  32. # its associated documentation for any purpose and without fee is
  33. # hereby granted, provided that the above copyright notice appears in
  34. # all copies, and that both that copyright notice and this permission
  35. # notice appear in supporting documentation, and that the name of
  36. # Secret Labs AB or the author not be used in advertising or publicity
  37. # pertaining to distribution of the software without specific, written
  38. # prior permission.
  39. #
  40. # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  41. # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
  42. # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
  43. # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  44. # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  45. # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  46. # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  47. # OF THIS SOFTWARE.
  48. # --------------------------------------------------------------------
  49. ##
  50. # Tools to build element trees from XML files, using <b>xmllib</b>.
  51. # This module can be used instead of the standard tree builder, for
  52. # Python versions where "expat" is not available (such as 1.5.2).
  53. # <p>
  54. # Note that due to bugs in <b>xmllib</b>, the namespace support is
  55. # not reliable (you can run the module as a script to find out exactly
  56. # how unreliable it is on your Python version).
  57. ##
  58. import xmllib, string
  59. import ElementTree
  60. ##
  61. # ElementTree builder for XML source data.
  62. #
  63. # @see elementtree.ElementTree
  64. class TreeBuilder(xmllib.XMLParser):
  65. def __init__(self, html=0):
  66. self.__builder = ElementTree.TreeBuilder()
  67. if html:
  68. import htmlentitydefs
  69. self.entitydefs.update(htmlentitydefs.entitydefs)
  70. xmllib.XMLParser.__init__(self)
  71. ##
  72. # Feeds data to the parser.
  73. #
  74. # @param data Encoded data.
  75. def feed(self, data):
  76. xmllib.XMLParser.feed(self, data)
  77. ##
  78. # Finishes feeding data to the parser.
  79. #
  80. # @return An element structure.
  81. # @defreturn Element
  82. def close(self):
  83. xmllib.XMLParser.close(self)
  84. return self.__builder.close()
  85. def handle_data(self, data):
  86. self.__builder.data(data)
  87. handle_cdata = handle_data
  88. def unknown_starttag(self, tag, attrs):
  89. attrib = {}
  90. for key, value in attrs.items():
  91. attrib[fixname(key)] = value
  92. self.__builder.start(fixname(tag), attrib)
  93. def unknown_endtag(self, tag):
  94. self.__builder.end(fixname(tag))
  95. def fixname(name, split=string.split):
  96. # xmllib in 2.0 and later provides limited (and slightly broken)
  97. # support for XML namespaces.
  98. if " " not in name:
  99. return name
  100. return "{%s}%s" % tuple(split(name, " ", 1))
  101. if __name__ == "__main__":
  102. import sys
  103. # sanity check: look for known namespace bugs in xmllib
  104. p = TreeBuilder()
  105. text = """\
  106. <root xmlns='default'>
  107. <tag attribute='value' />
  108. </root>
  109. """
  110. p.feed(text)
  111. tree = p.close()
  112. status = []
  113. # check for bugs in the xmllib implementation
  114. tag = tree.find("{default}tag")
  115. if tag is None:
  116. status.append("namespaces not supported")
  117. if tag is not None and tag.get("{default}attribute"):
  118. status.append("default namespace applied to unqualified attribute")
  119. # report bugs
  120. if status:
  121. print "xmllib doesn't work properly in this Python version:"
  122. for bug in status:
  123. print "-", bug
  124. else:
  125. print "congratulations; no problems found in xmllib"