Beispiel #1
0
    def test_xmlgen_ignorable_empty(self):
        result = self.ioclass()
        gen = XMLGenerator(result, short_empty_elements=True)

        gen.startDocument()
        gen.startElement("doc", {})
        gen.ignorableWhitespace(" ")
        gen.endElement("doc")
        gen.endDocument()

        self.assertEqual(result.getvalue(), self.xml("<doc> </doc>"))
Beispiel #2
0
    def test_xmlgen_ignorable(self):
        result = StringIO()
        gen = XMLGenerator(result)

        gen.startDocument()
        gen.startElement("doc", {})
        gen.ignorableWhitespace(" ")
        gen.endElement("doc")
        gen.endDocument()

        self.assertEquals(result.getvalue(), start + "<doc> </doc>")
Beispiel #3
0
    def test_xmlgen_ignorable(self):
        result = StringIO()
        gen = XMLGenerator(result)

        gen.startDocument()
        gen.startElement("doc", {})
        gen.ignorableWhitespace(" ")
        gen.endElement("doc")
        gen.endDocument()

        self.assertEqual(result.getvalue(), start + "<doc> </doc>")
Beispiel #4
0
    def test_xmlgen_ignorable_empty(self):
        result = self.ioclass()
        gen = XMLGenerator(result, short_empty_elements=True)

        gen.startDocument()
        gen.startElement("doc", {})
        gen.ignorableWhitespace(" ")
        gen.endElement("doc")
        gen.endDocument()

        self.assertEqual(result.getvalue(), self.xml("<doc> </doc>"))
Beispiel #5
0
def test_xmlgen_ignorable():
    result = StringIO()
    gen = XMLGenerator(result)

    gen.startDocument()
    gen.startElement("doc", {})
    gen.ignorableWhitespace(" ")
    gen.endElement("doc")
    gen.endDocument()

    return result.getvalue() == start + "<doc> </doc>"
Beispiel #6
0
def test_xmlgen_ignorable():
    result = StringIO()
    gen = XMLGenerator(result)

    gen.startDocument()
    gen.startElement("doc", {})
    gen.ignorableWhitespace(" ")
    gen.endElement("doc")
    gen.endDocument()

    return result.getvalue() == start + "<doc> </doc>"
Beispiel #7
0
 def test_xmlgen_encoding_bytes(self):
     encodings = ('iso-8859-15', 'utf-8', 'utf-8-sig', 'utf-16', 'utf-16be',
                  'utf-16le', 'utf-32', 'utf-32be', 'utf-32le')
     for encoding in encodings:
         result = self.ioclass()
         gen = XMLGenerator(result, encoding=encoding)
         gen.startDocument()
         gen.startElement('doc', {'a': '€'})
         gen.characters('€'.encode(encoding))
         gen.ignorableWhitespace(' '.encode(encoding))
         gen.endElement('doc')
         gen.endDocument()
         self.assertEqual(
             result.getvalue(),
             self.xml('<doc a="€">€ </doc>', encoding=encoding))
Beispiel #8
0
    def test_xmlgen_encoding_bytes(self):
        encodings = ('iso-8859-15', 'utf-8', 'utf-8-sig',
                     'utf-16', 'utf-16be', 'utf-16le',
                     'utf-32', 'utf-32be', 'utf-32le')
        for encoding in encodings:
            result = self.ioclass()
            gen = XMLGenerator(result, encoding=encoding)

            gen.startDocument()
            gen.startElement("doc", {"a": '\u20ac'})
            gen.characters("\u20ac".encode(encoding))
            gen.ignorableWhitespace(" ".encode(encoding))
            gen.endElement("doc")
            gen.endDocument()

            self.assertEqual(result.getvalue(),
                self.xml('<doc a="\u20ac">\u20ac </doc>', encoding=encoding))
Beispiel #9
0
    def test_xmlgen_encoding_bytes(self):
        encodings = ('iso-8859-15', 'utf-8', 'utf-8-sig', 'utf-16', 'utf-16be',
                     'utf-16le', 'utf-32', 'utf-32be', 'utf-32le')
        for encoding in encodings:
            result = self.ioclass()
            gen = XMLGenerator(result, encoding=encoding)

            gen.startDocument()
            gen.startElement("doc", {"a": '\u20ac'})
            gen.characters("\u20ac".encode(encoding))
            gen.ignorableWhitespace(" ".encode(encoding))
            gen.endElement("doc")
            gen.endDocument()

            self.assertEqual(
                result.getvalue(),
                self.xml('<doc a="\u20ac">\u20ac </doc>', encoding=encoding))
Beispiel #10
0
    def test_xmlgen_encoding_bytes(self):
        encodings = ('iso-8859-15', 'utf-8', 'utf-16be', 'utf-16le',
                     'utf-32be', 'utf-32le')
        for encoding in encodings:
            result = self.ioclass()
            gen = XMLGenerator(result, encoding=encoding)

            gen.startDocument()
            gen.startElement("doc", {"a": u'\u20ac'})
            gen.characters(u"\u20ac".encode(encoding))
            gen.ignorableWhitespace(" ".encode(encoding))
            gen.endElement("doc")
            gen.endDocument()

            self.assertEqual(result.getvalue(),
                             (u'<?xml version="1.0" encoding="%s"?>\n'
                              u'<doc a="\u20ac">\u20ac </doc>' %
                              encoding).encode(encoding, 'xmlcharrefreplace'))
Beispiel #11
0
    def test_xmlgen_encoding_bytes(self):
        encodings = ('iso-8859-15', 'utf-8',
                     'utf-16be', 'utf-16le',
                     'utf-32be', 'utf-32le')
        for encoding in encodings:
            result = self.ioclass()
            gen = XMLGenerator(result, encoding=encoding)

            gen.startDocument()
            gen.startElement("doc", {"a": u'\u20ac'})
            gen.characters(u"\u20ac".encode(encoding))
            gen.ignorableWhitespace(" ".encode(encoding))
            gen.endElement("doc")
            gen.endDocument()

            self.assertEqual(result.getvalue(), (
                u'<?xml version="1.0" encoding="%s"?>\n'
                u'<doc a="\u20ac">\u20ac </doc>' % encoding
                ).encode(encoding, 'xmlcharrefreplace'))
Beispiel #12
0
def main():
	optparser = optparse.OptionParser(usage="Usage: %prog [options] POFILE ...")
	optparser.add_option("-r", "--roundtrip", help="generate round-tripable output",
		action="store_true", dest="roundtrip", default=False)
	optparser.add_option("-o", "--output", help="write output to XMLFILE", metavar="XMLFILE",
		action="store", dest="output", default="-")
	(options, args) = optparser.parse_args()

	if options.output == "-":
		output = sys.stdout
	else:
		output = open(options.output, "w")

	writer = XMLGenerator(output or sys.stdout, "utf-8")
	writer.startDocument()
	writer.processingInstruction("xml-stylesheet", 'type="text/xsl" href="format-html.xsl"')
	writer.ignorableWhitespace("\n")

	writer.startElement("messages", {})
	writer.ignorableWhitespace("\n")

	msg = Message(writer, options.roundtrip)

	for l in fileinput.input(args):
		# Continuation string?
		m = re.match(r'\s*"(.*)"', l)
		if m:
			assert(msg.current)
			msg.current.append(unescape_c(m.group(1)))
			continue
		else:
			msg.flush()

		m = re.match(r'(?s)msgid "(.*)"', l)
		if m:
			msg.msgid = [unescape_c(m.group(1))]
			msg.current = msg.msgid
		m = re.match(r'(?s)msgstr "(.*)"', l)
		if m:
			msg.msgstr = [unescape_c(m.group(1))]
			msg.current = msg.msgstr

		m = re.match(r'# \s*(.*)', l)
		if m:
			msg.usrcomment.append(m.group(1))
		m = re.match(r'#\.\s*(.*)', l)
		if m:
			msg.dotcomment.append(m.group(1))
		m = re.match(r'#:\s*(.*)', l)
		if m:
			msg.reference.append(m.group(1))
		m = re.match(r'#,\s*(.*)', l)
		if m:
			msg.flags.append(m.group(1))

	msg.flush()

	writer.endElement("messages")
	writer.ignorableWhitespace("\n")
	writer.endDocument()
Beispiel #13
0
 def run(self):
     xml = XMLGenerator(self.out, 'UTF-8', True)
     xml.startDocument()
     xml.startPrefixMapping('', self.SVG_NAMESPACE)
     xml.startPrefixMapping(self.XLINK_PREFIX, self.XLINK_NAMESPACE)
     canvasWidth = int(self.marginWidth + (self.count - 1) * self.offset)
     attrs = self._defaultNSAttrs({
         self._svgName('version'):
         self.SVG_VERSION,
         self._svgName('width'):
         str(canvasWidth),
         self._svgName('height'):
         str(self.canvasHeight),
         self._svgName('viewBox'):
         ('%d %d %d %g' % (0, 0, canvasWidth, self.canvasHeight))
     })
     xml.startElementNS(self.SVG_ELEMENT, None, attrs)
     self._defs(xml)
     self._contentGroup(xml)
     xml.ignorableWhitespace('\n')
     xml.endElementNS(self.SVG_ELEMENT, None)
     xml.endPrefixMapping('')
     xml.endPrefixMapping(self.XLINK_PREFIX)
     xml.endDocument()
Beispiel #14
0
class StreamWriter(object):
  """This class provides methods for writing out an XML tree in a stream, rather than building it
  up in memory and then dumping it. The API is low-level, but it allows for very low memory usage,
  which is necessary when generating large files.

  This is implemented as a thin wrapper around xml.sax.saxutils.XMLGenerator.
  """
  def __init__(self, out, encoding="UTF-8", indent=None):
    """Initializes the StreamWriter instance.

    :out: a file-like object that will be written to
    :encodig: the encoding for output. Defaults to UTF-8
    :indent: a whitespace string used for indenting new lines. If None (the default) then no
             extra whitespace will be added to the document.
    """
    self._writer = XMLGenerator(out, encoding)
    self._indent = indent
    self._open_elements = []

  def __enter__(self):
    """Entry point for use as a context manager."""
    self.start()
    return self

  def __exit__(self, ex_type, ex_val, ex_tb):
    """Exit point for use as a context manager."""
    if ex_type is None:
      self.end()

  def start(self):
    """Calls startDocument on the underlying XMLGenerator."""
    self._writer.startDocument()

  def end(self):
    """Closes any remaining open elements and calls endDocument on the underlying XMLGenerator."""
    while self._open_elements:
      self.close()

    self._writer.endDocument()

  def open(self, name, attrs=None, *, close=False):
    """Writes an opening element.

    :name: the name of the element
    :attrs: a dict of attributes
    :close: if True, close will be called immediately after writing the element
    """
    self._pad()
    self._writer.startElement(_normalize_name(name), _normalize_attrs(attrs))
    self._newline()
    self._open_elements.append(name)

    if close:
      self.close()

  def close(self, name=None):
    """Closes the most recently opened element.

    :name: if given, this value must match the name given for the most recently opened element. This
           is primarily here for providing quick error checking for applications
    """
    tag = self._open_elements.pop()
    if name is not None and name != tag:
      raise Exception("Tag closing mismatch")
    self._pad()
    self._writer.endElement(_normalize_name(tag))
    self._newline()

  def characters(self, characters):
    """Writes content for a tag.

    :characters: the characters to write
    """
    self._pad()
    self._writer.characters(str(characters))
    self._newline()

  def whitespace(self, whitespace):
    """Writes ignorable whitespace.

    :whitespace: the whitespace to write
    """
    self._writer.ignorableWhitespace(whitespace)

  @contextmanager
  def element(self, name, attrs=None):
    """This method is a context manager for writing and closing an element."""
    self.open(name, attrs)
    yield
    self.close()

  @contextmanager
  def no_inner_space(self, *, outer=True):
    """Default spacing for all things written is ignored in this context.

    :outer: boolean, if True the typical padding and newline are added before the first and after
            the last things written
    """
    if outer:
      self._pad()

    indent_was = self._indent
    self._indent = None

    try:
      yield
    finally:
      self._indent = indent_was

    if outer:
      self._newline()

  def content(self, name, attrs=None, characters=None):
    """Writes an element, some content for the element, and then closes the element, all without
    indentation.

    :name: the name of the element
    :attrs: a dict of attributes
    :characters: the characters to write
    """
    with self.no_inner_space(outer=True):
      with self.element(name, attrs):
        if characters:
          self.characters(characters)

  def _pad(self):
    """Pads the output with an amount of indentation appropriate for the number of open element.

    This method does nothing if the indent value passed to the constructor is falsy.
    """
    if self._indent:
      self.whitespace(self._indent * len(self._open_elements))

  def _newline(self):
    """Writes a newline to output.

    This method does nothing if the indent value passed to the constructor is falsy.
    """
    if self._indent:
      self.whitespace("\n")
Beispiel #15
0
class EDXMLParser(EDXMLBase, XMLFilterBase):
  """The EDXMLParser class can be used as a content
  handler for Sax, and has several methods that
  can be overridden to implement custom EDXML processing
  scripts. It can optionally skip reading the event data
  itself if you are only interested in obtaining the 
  definitions. In that case, it will abort XML processing
  by raising the :class:`edxml.EDXMLBase.EDXMLProcessingInterrupted`
  exception, which you can catch and handle.

  Args:
    upstream: XML source (SaxParser instance in most cases)
    SkipEvents (bool, optional): Set to True to parse only the definitions section

  Attributes:
    Definitions (EDXMLDefinitions): :class:`edxml.EDXMLDefinitions.EDXMLDefinitions` instance
  """
  def __init__ (self, upstream, SkipEvents = False):

    self.EventCounters = {}
    self.TotalEventCount = 0
    self.SkipEvents = SkipEvents
    self.NewEventType = True
    self.AccumulatingEventContent = False
    self.CurrentEventContent = ''
    self.StreamCopyEnabled = False

    # This buffer will be used to compile a copy of the incoming EDXML
    # stream that has all event data filtered out. We use this stripped
    # copy to do RelaxNG validation, as Python has no incremental XML
    # validator like for instance PHP does.
    self.DefinitionsXMLStringIO = StringIO()

    # And this is the XMLGenerator instance that we will use
    # to fill the buffer.
    self.DefinitionsXMLGenerator = XMLGenerator(self.DefinitionsXMLStringIO, 'utf-8')

    """EDXMLDefinitions instance"""
    self.Definitions = EDXMLDefinitions()

    # We want the EDXMLDefinitions instance to call our
    # error handler, so anyone who wishes to extend the EDXMLParser
    # class can reimplement it to handle all generated errors.
    self.Definitions.Error = self.Error

    XMLFilterBase.__init__(self, upstream)
    EDXMLBase.__init__(self)

  def EndOfStream(self):
    """This method can be overridden to finish
    processing the event stream.

    The parser will call this method when the end of
    the EDXML stream has been reached.
    """
    return

  def ProcessEvent(self, EventTypeName, SourceId, EventObjects, EventContent, Parents):
    """This method can be overridden to process events. The
    EventObjects parameter contains a list of dictionaries, one
    for each object. Each dictionary has two keys. The 'property'
    key contains the name of the property. The 'value' key contains
    the value.

    Args:
      EventTypeName (str): The name of the event type

      SourceId (str): Event source identifier

      EventObjects (list): List of objects

      EventContent (str): String containing event content

      Parents (list): List of hashes of explicit parent events, as hexadecimal strings

    """
    return

  def ProcessObject(self, EventTypeName, ObjectProperty, ObjectValue):
    """This method can be overridden to process objects.

    The method will be called by the parser after reading an object element.

    Args:
      EventTypeName (str): The name of the event type

      ObjectProperty (str): The name of the object property

      ObjectValue (str): String containing object value

    """
    return

  def DefinitionsLoaded(self):
    """This method can be overridden to perform some
    action as soon as the definitions are read and parsed.

    The parser will call it as soon as the <definitions> element
    has been fully read and parsed. From that moment on, all
    event type and object type definitions can be access through
    the Definitions attribute of the parser instance.
    """
    return

  def GetEventCount(self, EventTypeName = None):
    """Returns the number of events parsed.

    When an event type is passed, only the number of events
    of this type is returned.

    Args:
      EventTypeName (str, optional): Name of an event type

    Returns:
      int. The number of events parsed.
    """
    if EventTypeName:
      if EventTypeName in self.EventCounters:
        return self.EventCounters[EventTypeName]
      else:
        return 0
    else:
      return self.TotalEventCount

  def GetWarningCount(self):
    """Returns the number of warnings issued

    Returns:
      int. The number of warnings issued.
    """
    return self.WarningCount + self.Definitions.GetWarningCount()

  def GetErrorCount(self):
    """Returns the number of errors issued

    Returns:
      int. The number of errors issued.
    """
    return self.ErrorCount + self.Definitions.GetErrorCount()

  def GetDefinitionsElementAsString(self):
    """Returns string representation of the <definitions> element

    Should not be called until the definitions tag has been fully
    fed to the parser.

    Returns:
      str. The XML string
    """
    return self.DefinitionsXMLStringIO.getvalue()

  def startElement(self, name, attrs):

    if name == 'eventgroup':
      SourceId = attrs.get('source-id')
      EventType = attrs.get('event-type')
      self.CurrentSourceId = SourceId
      self.CurrentEventTypeName = EventType
      if not EventType in self.EventCounters:
        self.EventCounters[EventType] = 0
      self.CurrentEventGroup = {'source-id': SourceId, 'event-type': EventType}
      if not self.Definitions.SourceIdDefined(SourceId):
        self.Error("An eventgroup refers to Source ID %s, which is not defined." % SourceId )
      if not self.Definitions.EventTypeDefined(EventType):
        self.Error("An eventgroup refers to eventtype %s, which is not defined." % EventType )

    elif name == 'definitions':
      self.StreamCopyEnabled = True

    elif name == 'source':
      Url = attrs.get('url')
      self.Definitions.AddSource(Url, dict(attrs.items()))

    elif name == 'eventtype':
      self.CurrentEventTypeProperties = []
      self.CurrentEventTypeName = attrs.get('name')
      if self.Definitions.EventTypeDefined(self.CurrentEventTypeName):
        self.NewEventType = False
      else:
        self.NewEventType = True
      self.Definitions.AddEventType(self.CurrentEventTypeName, dict(attrs.items()))

    elif name == 'property':
      PropertyName = attrs.get('name')
      self.CurrentEventTypeProperties.append(PropertyName)
      if not self.NewEventType:
        if not self.Definitions.PropertyDefined(self.CurrentEventTypeName, PropertyName):
          # Eventtype has been defined before, but this
          # property is not known in the existing eventtype
          # definition.
          self.Error("Property %s of eventtype %s did not exist in previous definition of this eventtype." % (( PropertyName, self.CurrentEventTypeName )) )
      self.Definitions.AddProperty(self.CurrentEventTypeName, PropertyName, dict(attrs.items()))

    elif name == 'parent':
      self.Definitions.SetEventTypeParent(self.CurrentEventTypeName, dict(attrs.items()))

    elif name == 'relation':
      Property1Name = attrs.get('property1')
      Property2Name = attrs.get('property2')
      if not self.NewEventType:
        if not self.Definitions.RelationDefined(self.CurrentEventTypeName, Property1Name, Property2Name):
          # Apparently, the relation was not defined in
          # the previous eventtype definition.
          self.Error("Relation between %s and %s in eventtype %s did not exist in previous definition of this eventtype." % (( Property1Name, Property2Name, self.CurrentEventTypeName )) )

      self.Definitions.AddRelation(self.CurrentEventTypeName, Property1Name, Property2Name, dict(attrs.items()))

    elif name == 'event':
      self.ExplicitEventParents = []
      if attrs.has_key('parents'): self.ExplicitEventParents = attrs.get('parents').split(',')
      self.EventObjects = []
      self.CurrentEventContent = ''

    elif name == 'content':
      self.AccumulatingEventContent = True

    elif name == 'object':
      ObjectProperty  = attrs.get('property')
      ObjectValue = attrs.get('value')
      self.ProcessObject(self.CurrentEventTypeName, ObjectProperty, ObjectValue)
      self.EventObjects.append({'property': ObjectProperty, 'value': ObjectValue})

    elif name == 'objecttype':
      ObjectTypeName = attrs.get('name')
      self.Definitions.AddObjectType(ObjectTypeName, dict(attrs.items()))

    if self.StreamCopyEnabled:
      self.DefinitionsXMLGenerator.startElement(name, attrs)

  def endElement(self, name):

    if self.StreamCopyEnabled:
      self.DefinitionsXMLGenerator.endElement(name)
      self.DefinitionsXMLGenerator.ignorableWhitespace("\n")

    if name == 'event':
      self.TotalEventCount += 1
      self.EventCounters[self.CurrentEventTypeName] += 1
      self.ProcessEvent(self.CurrentEventTypeName, self.CurrentSourceId, self.EventObjects, self.CurrentEventContent, self.ExplicitEventParents)

    elif name == 'content':
      self.AccumulatingEventContent = False

    elif name == 'definitions':

      self.StreamCopyEnabled = False

      # Invoke callback
      self.DefinitionsLoaded()

      if self.SkipEvents:

        # We hit the end of the definitions block,
        # and we were instructed to skip parsing the
        # event data, so we should abort parsing now.
        raise EDXMLProcessingInterrupted('')

    elif name == 'eventtype':
      if not self.NewEventType:
        self.Definitions.CheckEventTypePropertyConsistency(self.CurrentEventTypeName, self.CurrentEventTypeProperties)

    elif name == 'objecttypes':
      # Check if all objecttypes that properties
      # refer to are actually defined.
      self.Definitions.CheckPropertyObjectTypes()

    elif name == 'events':
      self.EndOfStream()

  def characters(self, text):

    if self.AccumulatingEventContent:
      self.CurrentEventContent += text
Beispiel #16
0
class XMLEncoderAdapter(object):
    """
    Adapts a WebAPIEncoder to output XML.

    This takes an existing encoder and adapts it to output a simple XML format.
    """

    def __init__(self, encoder, *args, **kwargs):
        self.encoder = encoder

    def encode(self, o, *args, **kwargs):
        self.level = 0
        self.doIndent = False

        stream = StringIO()
        self.xml = XMLGenerator(stream, settings.DEFAULT_CHARSET)
        self.xml.startDocument()
        self.startElement("rsp")
        self.__encode(o, *args, **kwargs)
        self.endElement("rsp")
        self.xml.endDocument()
        self.xml = None

        return stream.getvalue()

    def __encode(self, o, *args, **kwargs):
        if isinstance(o, dict):
            for key, value in o.iteritems():
                attrs = {}

                if isinstance(key, (int, long)):
                    attrs['value'] = str(key)
                    key = 'int'

                self.startElement(key, attrs)
                self.__encode(value, *args, **kwargs)
                self.endElement(key)
        elif isinstance(o, (tuple, list)):
            self.startElement("array")

            for i in o:
                self.startElement("item")
                self.__encode(i, *args, **kwargs)
                self.endElement("item")

            self.endElement("array")
        elif isinstance(o, basestring):
            self.text(o)
        elif isinstance(o, (int, long)):
            self.text("%d" % o)
        elif isinstance(o, bool):
            if o:
                self.text("True")
            else:
                self.text("False")
        elif o is None:
            pass
        else:
            result = self.encoder.encode(o, *args, **kwargs)

            if result is None:
                raise TypeError("%r is not XML serializable" % (o,))

            return self.__encode(result, *args, **kwargs)

    def startElement(self, name, attrs={}):
        self.addIndent()
        self.xml.startElement(name, attrs)
        self.level += 1
        self.doIndent = True

    def endElement(self, name):
        self.level -= 1
        self.addIndent()
        self.xml.endElement(name)
        self.doIndent = True

    def text(self, value):
        self.xml.characters(value)
        self.doIndent = False

    def addIndent(self):
        if self.doIndent:
            self.xml.ignorableWhitespace('\n' + ' ' * self.level)
class XmlAnnotationWriter:
    def __init__(self, file):
        self.version = "1.1"
        self.file = file
        self.xmlgen = XMLGenerator(self.file, 'utf-8')
        self._level = 0

    def _indent(self, newline=True):
        if newline:
            self.xmlgen.ignorableWhitespace("\n")
        self.xmlgen.ignorableWhitespace("  " * self._level)

    def _add_version(self):
        self._indent()
        self.xmlgen.startElement("version", {})
        self.xmlgen.characters(self.version)
        self.xmlgen.endElement("version")

    def open_root(self):
        self.xmlgen.startDocument()
        self.xmlgen.startElement("annotations", {})
        self._level += 1
        self._add_version()

    def _add_meta(self, meta):
        self._level += 1
        for k, v in meta.items():
            if isinstance(v, OrderedDict):
                self._indent()
                self.xmlgen.startElement(k, {})
                self._add_meta(v)
                self._indent()
                self.xmlgen.endElement(k)
            elif isinstance(v, list):
                self._indent()
                self.xmlgen.startElement(k, {})
                for tup in v:
                    self._add_meta(OrderedDict([tup]))
                self._indent()
                self.xmlgen.endElement(k)
            else:
                self._indent()
                self.xmlgen.startElement(k, {})
                self.xmlgen.characters(v)
                self.xmlgen.endElement(k)
        self._level -= 1

    def add_meta(self, meta):
        self._indent()
        self.xmlgen.startElement("meta", {})
        self._add_meta(meta)
        self._indent()
        self.xmlgen.endElement("meta")

    def open_track(self, track):
        self._indent()
        self.xmlgen.startElement("track", track)
        self._level += 1

    def open_image(self, image):
        self._indent()
        self.xmlgen.startElement("image", image)
        self._level += 1

    def open_box(self, box):
        self._indent()
        self.xmlgen.startElement("box", box)
        self._level += 1

    def open_polygon(self, polygon):
        self._indent()
        self.xmlgen.startElement("polygon", polygon)
        self._level += 1

    def open_polyline(self, polyline):
        self._indent()
        self.xmlgen.startElement("polyline", polyline)
        self._level += 1

    def open_points(self, points):
        self._indent()
        self.xmlgen.startElement("points", points)
        self._level += 1

    def open_cuboid(self, cuboid):
        self._indent()
        self.xmlgen.startElement("cuboid", cuboid)
        self._level += 1

    def open_tag(self, tag):
        self._indent()
        self.xmlgen.startElement("tag", tag)
        self._level += 1

    def add_attribute(self, attribute):
        self._indent()
        self.xmlgen.startElement("attribute", {"name": attribute["name"]})
        self.xmlgen.characters(attribute["value"])
        self.xmlgen.endElement("attribute")

    def close_box(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("box")

    def close_polygon(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("polygon")

    def close_polyline(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("polyline")

    def close_points(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("points")

    def close_cuboid(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("cuboid")

    def close_tag(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("tag")

    def close_image(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("image")

    def close_track(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("track")

    def close_root(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("annotations")
        self.xmlgen.endDocument()
Beispiel #18
0
# regression test for SAX 2.0
Beispiel #19
0
class UniversalXmlItemExporter(BaseItemExporter):
    def __init__(self, file, **kwargs):

        self._configure(kwargs)
        if not self.encoding:
            self.encoding = 'utf-8'
        self.encoding = self.encoding.upper()

        self.indent = settings.get('UXML_INDENT', 0)

        self.item_element = settings.get("UXML_ITEM", "item")
        self.root_element = settings.get("UXML_ROOT", "items")

        self.xg = XMLGenerator(file, encoding=self.encoding)

    def _beautify_newline(self, new_item=False):
        if self.indent is not None and (self.indent > 0 or new_item):
            self._xg_characters('\n')

    def _beautify_indent(self, depth=1):
        if self.indent:
            self._xg_characters(' ' * self.indent * depth)

    def start_exporting(self):
        self.xg.startDocument()
        self.xg.startElement(self.root_element, {})
        self._beautify_newline(new_item=True)

    def export_item(self, item):
        self._beautify_indent(depth=1)
        _attrs = {}
        for key in item.keys():
            if key.startswith("_"):
                _attrs[key[1:]] = item[key]
        _tag = self.item_element
        if "tag" in _attrs:
            _tag = _attrs.pop("tag")
        self.xg.startElement(_tag, _attrs)
        self._beautify_newline()
        for name, value in self._get_serialized_fields(item, default_value=''):
            if name.startswith("_"):
                continue
            _sub_attrs = {}
            if hasattr(value, 'items'):
                for key in value.keys():
                    if key.startswith("_"):
                        _sub_attrs[key[1:]] = value[key]
            _sub_tag = name
            if "tag" in _sub_attrs:
                _sub_tag = _sub_attrs.pop("tag")
            _out_value = None
            if "value" in _sub_attrs:
                _out_value = _sub_attrs.pop("value")

            self._export_xml_field(_sub_tag,
                                   value,
                                   depth=2,
                                   attrs=_sub_attrs,
                                   out_value=_out_value)
        self._beautify_indent(depth=1)
        self.xg.endElement(self.item_element)
        self._beautify_newline(new_item=True)

    def finish_exporting(self):
        self.xg.endElement(self.root_element)
        self.xg.endDocument()

    def _export_xml_field(self,
                          name,
                          serialized_value,
                          depth,
                          attrs=None,
                          out_value=None):
        self._beautify_indent(depth=depth)

        if attrs is None:
            attrs = {}
        if out_value is not None:
            serialized_value = out_value

        if serialized_value is None:
            self.xg.ignorableWhitespace("<%s/>" % name)
            self._beautify_newline()
            return

        self.xg.startElement(name, attrs)
        if hasattr(serialized_value, 'items'):
            self._beautify_newline()
            for subname, value in serialized_value.items():
                if subname.startswith("_"):
                    continue
                _attrs = {}

                if hasattr(value, 'items'):
                    for key in value.keys():
                        if key.startswith("_"):
                            _attrs[key[1:]] = value[key]

                _tag = subname
                if "tag" in _attrs:
                    _tag = _attrs.pop("tag")

                _out_value = None
                if "value" in _attrs:
                    _out_value = _attrs.pop("value")

                self._export_xml_field(_tag,
                                       value,
                                       depth=depth + 1,
                                       attrs=_attrs,
                                       out_value=_out_value)
            self._beautify_indent(depth=depth)
        elif is_listlike(serialized_value):
            self._beautify_newline()
            _is_dict_inside = True
            for value in serialized_value:
                if not hasattr(value, 'items'):
                    _is_dict_inside = False
                    break
            if _is_dict_inside:
                for value in serialized_value:
                    _sub_attrs = {}
                    for key in value.keys():
                        if key.startswith("_"):
                            _sub_attrs[key[1:]] = value[key]
                    _sub_tag = 'value'
                    if "tag" in _sub_attrs:
                        _sub_tag = _sub_attrs.pop("tag")

                    _sub_out_value = None
                    if "value" in _sub_attrs:
                        _sub_out_value = _sub_attrs.pop("value")

                    self._export_xml_field(_sub_tag,
                                           value,
                                           depth=depth + 1,
                                           out_value=_sub_out_value)
            else:
                for value in serialized_value:
                    self._export_xml_field('value', value, depth=depth + 1)
            self._beautify_indent(depth=depth)
        elif isinstance(serialized_value, six.text_type):
            self._xg_characters(serialized_value)
        else:
            self._xg_characters(str(serialized_value))
        self.xg.endElement(name)
        self._beautify_newline()

    # Workaround for https://bugs.python.org/issue17606
    # Before Python 2.7.4 xml.sax.saxutils required bytes;
    # since 2.7.4 it requires unicode. The bug is likely to be
    # fixed in 2.7.6, but 2.7.6 will still support unicode,
    # and Python 3.x will require unicode, so ">= 2.7.4" should be fine.
    if sys.version_info[:3] >= (2, 7, 4):

        def _xg_characters(self, serialized_value):
            if not isinstance(serialized_value, six.text_type):
                serialized_value = serialized_value.decode(self.encoding)
            return self.xg.characters(serialized_value)
    else:  # pragma: no cover

        def _xg_characters(self, serialized_value):
            return self.xg.characters(serialized_value)
Beispiel #20
0
class XmlWriter(WriterBase):
    """Writer for XML files
    
    Fulfills the Dispatcher interface.

    Arguments:
        os: Output stream    
    """
    def __init__(self, os=stdout, errorHandler=ErrorHandler()):
        super().__init__(errorHandler)
        self._impl= XMLGenerator(os, encoding="utf-8")
        self._indent = 2;
        self._stack= []
                           

    def startDocument(self):
        """Start new document
        """
        super().startDocument()
        self._impl.startDocument()
        self._stack.clear()
    
    
    def endDocument(self):
        """End current document
        """
        super().endDocument()
        self._impl.endDocument()
    
    
    def enterLeaf(self, name, attrs=dict()):
        """Enter leaf node
        
        Arguments:
            name (:class:`str`): Name of node
            attrs (:class:`dict`): Optional attributes
        """
        self.indent()
        self._impl.startElement(name, attrs)
        self._stack.append(name)

        
    def enterBranch(self, name, attrs=dict()):
        """Enter branch node
        
        Arguments:
            name (:class:`str`): Name of node
            attrs (:class:`dict`): Optional attributes
        """
        self.enterLeaf(name, attrs)
        self._impl.ignorableWhitespace("\n")
        
        
    def exitLeaf(self):
        """Exit current leaf node
        """
        self._impl.endElement( self._stack.pop() )
        self._impl.ignorableWhitespace("\n")


    def exitBranch(self):
        """Exit current branch node
        """
        self.indent(-1)
        self.exitLeaf()


    def writeContent(self, content):
        """Add content to current context

        Arguments:
            content(:class:`str`): String containing content
        """
        self._impl.characters(content)
        
       
    def writeComment(self, comment):
        """Add comment to current context

        Arguments:
            comment(:class:`str`): String containing comment
        """
        self.indent()
        self._impl.ignorableWhitespace("<!--{0}-->\n".format(comment))
        

    def indent(self, shift=0):
        """Print indentation level
        
        Arguments:
           shift (:class:`int`) : Shift indentation level by this amount
        """
        self._impl.ignorableWhitespace( self._indent
                                        * (shift + len(self._stack) )
                                        * " " )
Beispiel #21
0
class SphinxXML(object):

    TAG_ROOT = 'sphinx:docset'
    TAG_SCHEMA = 'sphinx:schema'
    TAG_DOCUMENT = 'sphinx:document'

    def __init__(self, output=stdout):
        self._generator = XMLGenerator(encoding='utf-8', out=output)
        self._output = output

        self._logger = logging.getLogger(self.__class__.__name__)

        self._schema = {'field': [], 'attr': []}
        self._document_id = 0

    def add_field(self, name):
        self._schema['field'].append({"name": name})

    def add_attr(self, name, attr_type, **kwargs):
        attr = kwargs
        attr['name'] = name
        attr['type'] = attr_type

        self._schema['attr'].append(attr)

    def start(self):
        self._generator.startDocument()
        self._generator.startElement(
            self.TAG_ROOT, {'xmlns:sphinx': 'http://sphinxsearch.com/'})

        # print schema
        self._generator.ignorableWhitespace("\n\n")
        self._generator.startElement(self.TAG_SCHEMA, {})

        for key, items in self._schema.items():
            for item in items:
                self._generator.ignorableWhitespace("\n\t")
                self._generator.startElement('sphinx:{}'.format(key),
                                             attrs=item)
                self._generator.endElement('sphinx:{}'.format(key))

        self._generator.ignorableWhitespace("\n")
        self._generator.endElement(self.TAG_SCHEMA)
        self._generator.ignorableWhitespace("\n\n")
        self._output.flush()

    def add_document(self, **kwargs):
        # auto-generate incrementing document IDs
        self._document_id += 1

        self._logger.info('Adding document #{}'.format(self._document_id))
        self._generator.startElement(self.TAG_DOCUMENT,
                                     {"id": str(self._document_id)})

        try:
            for key, val in kwargs.items():
                self._generator.ignorableWhitespace("\n\t")
                self._generator.startElement(key, {})
                self._generator.characters(val)
                self._generator.endElement(key)
        except ValueError:
            self._logger.error('add_document failed (doc ID #{})'.format(
                self._document_id),
                               exc_info=True)

        self._generator.ignorableWhitespace("\n")
        self._generator.endElement(self.TAG_DOCUMENT)
        self._generator.ignorableWhitespace("\n\n")
        self._output.flush()

    def end(self):
        self._generator.endElement(self.TAG_ROOT)
        self._generator.endDocument()

        self._logger.info('XML closed')
Beispiel #22
0
class _XmlAnnotationWriter(_AnnotationWriter):
    def __init__(self, file):
        super().__init__(file, "1.0")
        self.xmlgen = XMLGenerator(self.file, 'utf-8')
        self._level = 0

    def _indent(self, newline=True):
        if newline:
            self.xmlgen.ignorableWhitespace("\n")
        self.xmlgen.ignorableWhitespace("  " * self._level)

    def _add_version(self):
        self._indent()
        self.xmlgen.startElement("version", {})
        self.xmlgen.characters(self.version)
        self.xmlgen.endElement("version")

    def open_root(self):
        self.xmlgen.startDocument()
        self.xmlgen.startElement("annotations", {})
        self._level += 1
        self._add_version()

    def _add_meta(self, meta):
        self._level += 1
        for k, v in meta.items():
            if isinstance(v, OrderedDict):
                self._indent()
                self.xmlgen.startElement(k, {})
                self._add_meta(v)
                self._indent()
                self.xmlgen.endElement(k)
            else:
                self._indent()
                self.xmlgen.startElement(k, {})
                self.xmlgen.characters(v)
                self.xmlgen.endElement(k)
        self._level -= 1

    def add_meta(self, meta):
        self._indent()
        self.xmlgen.startElement("meta", {})
        self._add_meta(meta)
        self._indent()
        self.xmlgen.endElement("meta")

    def open_track(self, track):
        self._indent()
        self.xmlgen.startElement("track", track)
        self._level += 1

    def open_image(self, image):
        self._indent()
        self.xmlgen.startElement("image", image)
        self._level += 1

    def open_box(self, box):
        self._indent()
        self.xmlgen.startElement("box", box)
        self._level += 1

    def add_attribute(self, attribute):
        self._indent()
        self.xmlgen.startElement("attribute", {"name": attribute["name"]})
        self.xmlgen.characters(attribute["value"])
        self.xmlgen.endElement("attribute")

    def close_box(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("box")

    def close_image(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("image")

    def close_track(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("track")

    def close_root(self):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement("annotations")
        self.xmlgen.endDocument()
Beispiel #23
0
class XMLEncoderAdapter(object):
    """Adapts a WebAPIEncoder to output XML.

    This takes an existing encoder and adapts it to output a simple XML format.
    """
    def __init__(self, encoder, *args, **kwargs):
        self.encoder = encoder

    def encode(self, o, *args, **kwargs):
        self.level = 0
        self.doIndent = False

        stream = StringIO()
        self.xml = XMLGenerator(stream, settings.DEFAULT_CHARSET)
        self.xml.startDocument()
        self.startElement("rsp")
        self.__encode(o, *args, **kwargs)
        self.endElement("rsp")
        self.xml.endDocument()
        self.xml = None

        return stream.getvalue()

    def __encode(self, o, *args, **kwargs):
        if isinstance(o, dict):
            for key, value in six.iteritems(o):
                attrs = {}

                if isinstance(key, six.integer_types):
                    attrs['value'] = str(key)
                    key = 'int'

                self.startElement(key, attrs)
                self.__encode(value, *args, **kwargs)
                self.endElement(key)
        elif isinstance(o, (tuple, list)):
            self.startElement("array")

            for i in o:
                self.startElement("item")
                self.__encode(i, *args, **kwargs)
                self.endElement("item")

            self.endElement("array")
        elif isinstance(o, six.string_types):
            self.text(o)
        elif isinstance(o, six.integer_types):
            self.text("%d" % o)
        elif isinstance(o, float):
            self.text("%s" % o)
        elif isinstance(o, bool):
            if o:
                self.text("True")
            else:
                self.text("False")
        elif o is None:
            pass
        else:
            result = self.encoder.encode(o, *args, **kwargs)

            if result is None:
                raise TypeError("%r is not XML serializable" % (o,))

            return self.__encode(result, *args, **kwargs)

    def startElement(self, name, attrs={}):
        self.addIndent()
        self.xml.startElement(name, attrs)
        self.level += 1
        self.doIndent = True

    def endElement(self, name):
        self.level -= 1
        self.addIndent()
        self.xml.endElement(name)
        self.doIndent = True

    def text(self, value):
        self.xml.characters(value)
        self.doIndent = False

    def addIndent(self):
        if self.doIndent:
            self.xml.ignorableWhitespace('\n' + ' ' * self.level)
Beispiel #24
0
class ClipExtractor(ContentHandler):
    def __init__(self, output, clipId):
        self._sink = XMLGenerator(output, 'UTF-8', True)
        self._locator = None
        self._id = clipId

    def setDocumentLocator(self, locator):
        self._locator = locator
        self._skip = None
        self._stopAt = None
        return self._sink.setDocumentLocator(locator)

    def startDocument(self):
        #         self._prefixes = {}
        self.scale = self.units = None
        self._context = []
        self._outerSvgRendered = False
        return self._sink.startDocument()

    def endDocument(self):
        #         self._prefixes.clear()
        return self._sink.endDocument()

    def startPrefixMapping(self, prefix, uri):
        self._context.append(('xmlns', None, prefix, uri))
        #         mappings = self._prefixes.get(prefix)
        #         if mappings is None:
        #             self._prefixes[prefix] = mappings = []
        #         mappings.append(uri)
        return self._sink.startPrefixMapping(prefix, uri)

    def endPrefixMapping(self, prefix):
        context = self._context.pop()
        assert ('xmlns', None, prefix) == context[:-1]
        #         mappings = self._prefixes.get(prefix)
        #         assert mappings is not None
        #         mappings.pop()
        return self._sink.endPrefixMapping(prefix)

    def startElement(self, qname, attrs):
        raise xml.sax.SAXNotSupportedException(
            'This handler must be used with feature "%s"'
            ' turned on' % xml.sax.handler.feature_namespaces)
#         if 'xmlns' in attrs:
#             if self._context:
#                 raise xml.sax.SAXNotSupportedException(
#                     'This document must be parsed with feature "%s"'
#                     ' turned on'
#                     % xml.sax.handler.feature_namespaces
#                 )
#             else:
#                 self.startPrefixMapping('', attrs.get('xmlns'))
#         ns, name = self._splitNS(qname)
#         handler = self.ELEMENTS.get((ns, name))
#         if handler and handler[0]:
#             update = handler[0](self, attrs, ns, name)
#             if not update:
#                 if self._skip is None:
#                     self._skip = len(self._context) + 1
#             elif isinstance(update, collections.Sequence):
#                 attrs = update[0]
#                 if len(update) > 1:
#                     ns, name, qname = update[1:]
#         self._context.append((ns, name, qname, attrs.copy()))
#         if self._skip is None:
#             return self._sink.startElement(qname, attrs)

    def endElement(self, qname):
        raise xml.sax.SAXNotSupportedException(
            'This handler must be used with feature "%s"'
            ' turned on' % xml.sax.handler.feature_namespaces)
#         ns, name = self._splitNS(qname)
#         handler = self.ELEMENTS.get((ns, name))
#         if handler and handler[1]:
#             handler[1](self, ns, name)
#         context = self._context.pop()
#         assert (ns, name) == context[:2]
#         if self._skip is None:
#             self._sink.endElement(qname)
#         elif len(self._context) < self._skip:
#             self._skip = None
#         if len(self._context) == self._stopAt:
#             raise self.Done('extraction complete',
#                             self._locator.getLineNumber(),
#                             self._locator.getColumnNumber()
#                         )

    def startElementNS(self, name, qname, attrs):
        if (None, 'xmlns') in attrs:
            self.startPrefixMapping(None, attrs.get('xmlns'))
        handler = self.ELEMENTS.get(name)
        if handler and handler[0]:
            update = handler[0](self, attrs, *name, qname)
            if not update:
                if self._skip is None:
                    self._skip = len(self._context) + 1
            elif isinstance(update, collections.Sequence):
                attrs = update[0]
                if len(update) > 1:
                    name = tuple(update[1:3])
                if len(update) > 3:
                    qname = update[3]
        self._context.append(name + (qname, attrs.copy()))
        if self._skip is None:
            return self._sink.startElementNS(name, qname, attrs)

    def endElementNS(self, name, qname):
        handler = self.ELEMENTS.get(name)
        if handler and handler[1]:
            handler[1](self, *name, qname)
        context = self._context.pop()
        assert name == context[:2]
        if self._skip is None:
            self._sink.endElementNS(name, qname)
        elif len(self._context) < self._skip:
            self._skip = None
        if len(self._context) == self._stopAt:
            while self._context:
                toClose = self._context.pop()
                if 'xmlns' == toClose[0]:
                    self._sink.endPrefixMapping(toClose[2])
                else:
                    self._sink.ignorableWhitespace('\n')
                    self._sink.endElementNS(toClose[:2], toClose[2])
            self._sink.endDocument()
            raise self.Done('extraction complete',
                            (self._locator.getLineNumber(),
                             self._locator.getColumnNumber()))

    def elementSvgEnd(self, *args):
        attrs = self._context[-1][3]
        if self.ATTR_ID in attrs and \
                self._id == attrs.get(self.ATTR_ID):
            self._stopAt = len(self._context) - 1

    def elementSvgStart(self, attrs, *args):
        if any((CardBackView.SVG_NAMESPACE, 'svg') == e[:2]
               for e in self._context):
            return self.ATTR_ID in attrs and \
                self._id == attrs.get(self.ATTR_ID)
        elif not 'viewBox' in attrs and not (None, 'viewBox') in attrs:
            self._error(None, 'Main <svg> element has no viewBox attribute')
        else:
            try:
                internalSize = attrs.get((None, 'viewBox'))
                if internalSize is None:
                    internalSize = attrs.get('viewBox')
                internalSize = self.parseBox(internalSize)[2:]
                externalSize = list(internalSize)
                units = [''] * 2
                i = -1
                for attr in CardBackView.ATTRS_SVG_DIMENSION:
                    i += 1
                    value, unit = self._distanceAttr(attrs, attr)
                    if unit.strip() == '%':
                        value = None
                    if value is not None:
                        externalSize[i] = value
                        units[i] = unit
                self.units = tuple(units)
                try:
                    self.scale = tuple(
                        e / i for e, i in zip(externalSize, internalSize))
                except ZeroDivisionError as error:
                    self._error(
                        None,
                        'Found <svg> with zero dimension(s), viewBox="%s"' %
                        attrs.get((None, 'viewBox')))
                return False
            except:
                self._error()

    def elementUseStart(self, attrs, ns, name, qname):
        target = attrs.get(CardBackView.XLINK_HREF_ATTR)
        if not target:
            return False
        target = target.strip()
        if '#' == target[0] and self._id == target[1:] \
             and not self._outerSvgRendered:
            try:
                outerSvg = next(e for e in self._context
                                if (CardBackView.SVG_NAMESPACE,
                                    'svg') == e[:2])
            except StopIteration:
                self._error(None, 'Found <use> element outside of an <svg>')
            size = []
            for attr in CardBackView.ATTRS_SVG_DIMENSION:
                value, unit = self._distanceAttr(attrs, attr)
                if unit.strip():
                    self._error(
                        None, 'Attribute <use %s="%s" ...> is not valid'
                        ' in this context, expected a unit-free number.' %
                        (attr, attrs.get(None, attr)))
                if value is None:
                    self._error(
                        None, 'Attribute `%s` is missing from <use> element,'
                        ' but is expected in this context.' % attr)
                size.append(value)
            sattrs = ('%.6f%s' % (s * v, u)
                      for s, v, u in zip(self.scale, size, self.units))
            qnames = {
                name: outerSvg[3].getQNameByName(name)
                for name in outerSvg[3].getNames()
            }
            attrMap = dict(outerSvg[3].items())
            attrMap[(None, 'viewBox')] = self.boxValue((0, 0) + tuple(size))
            for attr in zip(CardBackView.ATTRS_SVG_DIMENSION, sattrs):
                attrMap[(None, attr[0])] = attr[1]
            self._sink.startElementNS(outerSvg[:2], outerSvg[2],
                                      AttributesNSImpl(attrMap, qnames))
            self._sink.ignorableWhitespace('\n')
            self._outerSvgRendered = True
            qnames = {
                name: attrs.getQNameByName(name)
                for name in attrs.getNames()
            }
            attrMap = dict(attrs.items())
            for attr in ('x', 'y') + CardBackView.ATTRS_SVG_DIMENSION:
                qnames.pop((None, attr), None)
                attrMap.pop((None, attr), None)
            self._sink.startElementNS((ns, name), qname,
                                      AttributesNSImpl(attrMap, qnames))
            self._sink.endElementNS((ns, name), qname)
            self._sink.ignorableWhitespace('\n')
        return False

    def elementDefsStart(self, attrs, *args):
        if not self._outerSvgRendered:
            self._error(
                None, 'Element <use xlink:href="#%s" ...> must precede'
                ' the <defs> element in this context.' % self._id)
        self._skip = None
        return True

    ATTR_ID = (None, 'id')

    ELEMENTS = {
        (CardBackView.SVG_NAMESPACE, 'svg'): (elementSvgStart, elementSvgEnd),
        (CardBackView.SVG_NAMESPACE, 'use'): (elementUseStart, None),
        (CardBackView.SVG_NAMESPACE, 'defs'): (elementDefsStart, None),
    }

    def characters(self, content):
        if self._skip is None:
            return self._sink.characters(content)

    def ignorableWhitespace(self, whitespace):
        if self._skip is None:
            return self._sink.ignorableWhitespace(whitespace)

    def processingInstruction(self, target, data):
        if self._skip is None:
            return self._sink.processingInstruction(target, data)

    def skippedEntity(self, name):
        if self._skip is None:
            return self._sink.skippedEntity(name)

    def _error(self, error=True, message=''):
        if error == True:
            error = sys.exc_info()[1]
        if error is None:
            assert message
            error = SAXParseException(message, None, self._locator)
        elif not isinstance(error, SAXParseException):
            msg = error.args[0] if error.args else ''
            if msg:
                msg += ' '
            if message:
                msg += message + ' '
            error.args = (msg + 'at line %d, column %d.' %
                          (self._locator.getLineNumber(),
                           self._locator.getColumnNumber()), ) + error.args[1:]
        raise error

    class Done(xml.sax.SAXException):
        pass
Beispiel #25
0
class _XmlAnnotationWriter:
    # Format constants
    _tracking_level = 0

    _tracklets_class_id = 0
    _tracklets_version = 0

    _tracklet_class_id = 1
    _tracklet_version = 1

    _poses_class_id = 2
    _poses_version = 0

    _pose_class_id = 3
    _pose_version = 1

    # XML headers
    _header = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>"""
    _doctype = "<!DOCTYPE boost_serialization>"

    def __init__(self, file, tracklets):
        self._file = file
        self._tracklets = tracklets

        self._xmlgen = XMLGenerator(self._file, encoding='utf-8')
        self._level = 0

        # See reference for section headers here:
        # https://www.boost.org/doc/libs/1_40_0/libs/serialization/doc/traits.html
        # XML archives have regular structure, so we only include headers once
        self._add_tracklet_header = True
        self._add_poses_header = True
        self._add_pose_header = True

    def _indent(self, newline=True):
        if newline:
            self._xmlgen.ignorableWhitespace("\n")
        self._xmlgen.ignorableWhitespace("  " * self._level)

    def _add_headers(self):
        self._file.write(self._header)

        self._indent(newline=True)
        self._file.write(self._doctype)

    def _open_serialization(self):
        self._indent(newline=True)
        self._xmlgen.startElement("boost_serialization", {
            "version": "9", "signature": "serialization::archive"
        })

    def _close_serialization(self):
        self._indent(newline=True)
        self._xmlgen.endElement("boost_serialization")

    def _add_count(self, count):
        self._indent(newline=True)
        self._xmlgen.startElement("count", {})
        self._xmlgen.characters(str(count))
        self._xmlgen.endElement("count")

    def _add_item_version(self, version):
        self._indent(newline=True)
        self._xmlgen.startElement("item_version", {})
        self._xmlgen.characters(str(version))
        self._xmlgen.endElement("item_version")

    def _open_tracklets(self, tracklets):
        self._indent(newline=True)
        self._xmlgen.startElement("tracklets", {
            "version": str(self._tracklets_version),
            "tracking_level": str(self._tracking_level),
            "class_id": str(self._tracklets_class_id),
        })
        self._level += 1
        self._add_count(len(tracklets))
        self._add_item_version(self._tracklet_version)

    def _close_tracklets(self):
        self._level -= 1
        self._indent(newline=True)
        self._xmlgen.endElement("tracklets")

    def _open_tracklet(self):
        self._indent(newline=True)
        if self._add_tracklet_header:
            self._xmlgen.startElement("item", {
                "version": str(self._tracklet_class_id),
                "tracking_level": str(self._tracking_level),
                "class_id": str(self._tracklet_class_id),
            })
            self._add_tracklet_header = False
        else:
            self._xmlgen.startElement("item", {})
        self._level += 1

    def _close_tracklet(self):
        self._level -= 1
        self._indent(newline=True)
        self._xmlgen.endElement("item")

    def _add_tracklet(self, tracklet):
        self._open_tracklet()

        for key, value in tracklet.items():
            if key == "poses":
                self._add_poses(value)
            elif key == "attributes":
                self._add_attributes(value)
            else:
                self._indent(newline=True)
                self._xmlgen.startElement(key, {})
                self._xmlgen.characters(str(value))
                self._xmlgen.endElement(key)

        self._close_tracklet()

    def _open_poses(self, poses):
        self._indent(newline=True)
        if self._add_poses_header:
            self._xmlgen.startElement("poses", {
                "version": str(self._poses_version),
                "tracking_level": str(self._tracking_level),
                "class_id": str(self._poses_class_id),
            })
            self._add_poses_header = False
        else:
            self._xmlgen.startElement("poses", {})
        self._level += 1

        self._add_count(len(poses))
        self._add_item_version(self._poses_version)

    def _close_poses(self):
        self._level -= 1
        self._indent(newline=True)
        self._xmlgen.endElement("poses")

    def _add_poses(self, poses):
        self._open_poses(poses)

        for pose in poses:
            self._add_pose(pose)

        self._close_poses()

    def _open_pose(self):
        self._indent(newline=True)
        if self._add_pose_header:
            self._xmlgen.startElement("item", {
                "version": str(self._pose_version),
                "tracking_level": str(self._tracking_level),
                "class_id": str(self._pose_class_id),
            })
            self._add_pose_header = False
        else:
            self._xmlgen.startElement("item", {})
        self._level += 1

    def _close_pose(self):
        self._level -= 1
        self._indent(newline=True)
        self._xmlgen.endElement("item")

    def _add_pose(self, pose):
        self._open_pose()

        for key, value in pose.items():
            if key == 'attributes':
                self._add_attributes(value)
            elif key != 'frame_id':
                self._indent(newline=True)
                self._xmlgen.startElement(key, {})
                self._xmlgen.characters(str(value))
                self._xmlgen.endElement(key)

        self._close_pose()

    def _open_attributes(self):
        self._indent(newline=True)
        self._xmlgen.startElement("attributes", {})
        self._level += 1

    def _close_attributes(self):
        self._level -= 1
        self._indent(newline=True)
        self._xmlgen.endElement("attributes")

    def _add_attributes(self, attributes):
        self._open_attributes()

        for name, value in attributes.items():
            self._add_attribute(name, value)

        self._close_attributes()

    def _open_attribute(self):
        self._indent(newline=True)
        self._xmlgen.startElement("attribute", {})
        self._level += 1

    def _close_attribute(self):
        self._level -= 1
        self._indent(newline=True)
        self._xmlgen.endElement("attribute")

    def _add_attribute(self, name, value):
        self._open_attribute()

        self._indent(newline=True)
        self._xmlgen.startElement("name", {})
        self._xmlgen.characters(name)
        self._xmlgen.endElement("name")

        self._xmlgen.startElement("value", {})
        self._xmlgen.characters(str(value))
        self._xmlgen.endElement("value")

        self._close_attribute()

    def write(self):
        self._add_headers()
        self._open_serialization()

        self._open_tracklets(self._tracklets)

        for tracklet in self._tracklets:
            self._add_tracklet(tracklet)

        self._close_tracklets()

        self._close_serialization()
Beispiel #26
0
class main(object):
    def __init__(self, f):
        stream = StringIO()

        self.input = f

        self.xml = XMLGenerator(stream, "UTF-8")
        self.xml.startDocument()
        self.xml.startElement(
            '!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"', {}
        )
        self.xml.ignorableWhitespace("\n")
        self.xml.startElement("plist", {"version": "1.0"})
        self.xml.ignorableWhitespace("\n")
        self.xml.startElement("array", {})
        # self.xml.ignorableWhitespace('\n')

        self.generate_sections()

        self.xml.ignorableWhitespace("\n")
        self.xml.endElement("array")
        self.xml.ignorableWhitespace("\n")
        self.xml.endElement("plist")

        from pprint import pprint

        # pprint(dir(self.xml))

        stream.seek(0)
        print stream.read()

    def generate_sections(self):
        section_name = None
        translation_pairs = []

        for line in self.input:
            if line.strip():
                if section_name is None:
                    section_name = line.strip()
                    continue

                if line.startswith(" "):
                    orig, trans = [s.strip() for s in line.split("~", 1)]
                    translation_pairs.append((orig, trans))
                else:
                    self.generate_section(section_name, translation_pairs)
                    section_name = line.strip()
                    translation_pairs = []

        if section_name:
            self.generate_section(section_name, translation_pairs)

    def generate_section(self, section_name, translation_pairs):
        self.indent(1)
        self.xml.startElement("dict", {})

        self.indent(2)
        self.xml.startElement("key", {})
        self.xml.characters("sectionData")
        self.xml.endElement("key")

        self.indent(2)
        self.xml.startElement("array", {})

        for orig, trans in translation_pairs:
            self.generate_translation_pair(orig, trans)

        self.indent(2)
        self.xml.endElement("array")

        self.indent(2)
        self.xml.startElement("key", {})
        self.xml.characters("sectionName")
        self.xml.endElement("key")

        self.indent(2)
        self.xml.startElement("string", {})
        self.xml.characters(section_name)
        self.xml.endElement("string")

        self.indent(1)
        self.xml.endElement("dict")

    def generate_translation_pair(self, orig, trans):
        self.indent(3)
        self.xml.startElement("dict", {})

        self.indent(4)
        self.xml.startElement("key", {})
        self.xml.characters("orig")
        self.xml.endElement("key")

        self.indent(4)
        self.xml.startElement("string", {})
        self.xml.characters(orig)
        self.xml.endElement("string")

        self.indent(4)
        self.xml.startElement("key", {})
        self.xml.characters("trans")
        self.xml.endElement("key")

        self.indent(4)
        self.xml.startElement("string", {})
        self.xml.characters(trans)
        self.xml.endElement("string")

        self.indent(3)
        self.xml.endElement("dict")

    def indent(self, level):
        self.xml.ignorableWhitespace("\n" + " " * 4 * level)
Beispiel #27
0
class XmlAnnotationWriter:
    VERSION = '1.1'

    def __init__(self, f):
        self.xmlgen = XMLGenerator(f, 'utf-8')
        self._level = 0

    def _indent(self, newline=True):
        if newline:
            self.xmlgen.ignorableWhitespace('\n')
        self.xmlgen.ignorableWhitespace('  ' * self._level)

    def _add_version(self):
        self._indent()
        self.xmlgen.startElement('version', {})
        self.xmlgen.characters(self.VERSION)
        self.xmlgen.endElement('version')

    def open_root(self):
        self.xmlgen.startDocument()
        self.xmlgen.startElement('annotations', {})
        self._level += 1
        self._add_version()

    def _add_meta(self, meta):
        self._level += 1
        for k, v in meta.items():
            if isinstance(v, OrderedDict):
                self._indent()
                self.xmlgen.startElement(k, {})
                self._add_meta(v)
                self._indent()
                self.xmlgen.endElement(k)
            elif isinstance(v, list):
                self._indent()
                self.xmlgen.startElement(k, {})
                for tup in v:
                    self._add_meta(OrderedDict([tup]))
                self._indent()
                self.xmlgen.endElement(k)
            else:
                self._indent()
                self.xmlgen.startElement(k, {})
                self.xmlgen.characters(v)
                self.xmlgen.endElement(k)
        self._level -= 1

    def write_meta(self, meta):
        self._indent()
        self.xmlgen.startElement('meta', {})
        self._add_meta(meta)
        self._indent()
        self.xmlgen.endElement('meta')

    def open_track(self, track):
        self._indent()
        self.xmlgen.startElement('track', track)
        self._level += 1

    def open_image(self, image):
        self._indent()
        self.xmlgen.startElement('image', image)
        self._level += 1

    def open_box(self, box):
        self._indent()
        self.xmlgen.startElement('box', box)
        self._level += 1

    def open_polygon(self, polygon):
        self._indent()
        self.xmlgen.startElement('polygon', polygon)
        self._level += 1

    def open_polyline(self, polyline):
        self._indent()
        self.xmlgen.startElement('polyline', polyline)
        self._level += 1

    def open_points(self, points):
        self._indent()
        self.xmlgen.startElement('points', points)
        self._level += 1

    def open_tag(self, tag):
        self._indent()
        self.xmlgen.startElement("tag", tag)
        self._level += 1

    def add_attribute(self, attribute):
        self._indent()
        self.xmlgen.startElement('attribute', {'name': attribute['name']})
        self.xmlgen.characters(attribute['value'])
        self.xmlgen.endElement('attribute')

    def _close_element(self, element):
        self._level -= 1
        self._indent()
        self.xmlgen.endElement(element)

    def close_box(self):
        self._close_element('box')

    def close_polygon(self):
        self._close_element('polygon')

    def close_polyline(self):
        self._close_element('polyline')

    def close_points(self):
        self._close_element('points')

    def close_tag(self):
        self._close_element('tag')

    def close_image(self):
        self._close_element('image')

    def close_track(self):
        self._close_element('track')

    def close_root(self):
        self._close_element('annotations')
        self.xmlgen.endDocument()
Beispiel #28
0
class SphinxXML(object):

    TAG_ROOT = 'sphinx:docset'
    TAG_SCHEMA = 'sphinx:schema'
    TAG_DOCUMENT = 'sphinx:document'

    def __init__(self, output=stdout):
        self._generator = XMLGenerator(encoding='utf-8', out=output)
        self._output = output

        self._logger = logging.getLogger(self.__class__.__name__)

        self._schema = {
            'field': [],
            'attr': []
        }
        self._document_id = 0

    def add_field(self, name):
        self._schema['field'].append({
            "name": name
        })

    def add_attr(self, name, attr_type, **kwargs):
        attr = kwargs
        attr['name'] = name
        attr['type'] = attr_type

        self._schema['attr'].append(attr)

    def start(self):
        self._generator.startDocument()
        self._generator.startElement(self.TAG_ROOT, {'xmlns:sphinx': 'http://sphinxsearch.com/'})

        # print schema
        self._generator.ignorableWhitespace("\n\n")
        self._generator.startElement(self.TAG_SCHEMA, {})

        for key, items in self._schema.items():
            for item in items:
                self._generator.ignorableWhitespace("\n\t")
                self._generator.startElement('sphinx:{}'.format(key), attrs=item)
                self._generator.endElement('sphinx:{}'.format(key))

        self._generator.ignorableWhitespace("\n")
        self._generator.endElement(self.TAG_SCHEMA)
        self._generator.ignorableWhitespace("\n\n")
        self._output.flush()

    def add_document(self, **kwargs):
        # auto-generate incrementing document IDs
        self._document_id += 1

        self._logger.info('Adding document #{}'.format(self._document_id))
        self._generator.startElement(self.TAG_DOCUMENT, {"id": str(self._document_id)})

        try:
            for key, val in kwargs.items():
                self._generator.ignorableWhitespace("\n\t")
                self._generator.startElement(key, {})
                self._generator.characters(val)
                self._generator.endElement(key)
        except ValueError:
            self._logger.error('add_document failed (doc ID #{})'.format(self._document_id), exc_info=True)

        self._generator.ignorableWhitespace("\n")
        self._generator.endElement(self.TAG_DOCUMENT)
        self._generator.ignorableWhitespace("\n\n")
        self._output.flush()

    def end(self):
        self._generator.endElement(self.TAG_ROOT)
        self._generator.endDocument()

        self._logger.info('XML closed')