MarkupWriter.py :  » XML » 4Suite » 4Suite-XML-1.0.2 » Ft » Xml » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » XML » 4Suite 
4Suite » 4Suite XML 1.0.2 » Ft » Xml » MarkupWriter.py
########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Xml/MarkupWriter.py,v 1.6 2005/09/13 22:59:35 uogbuji Exp $
"""
MarkupWriter provides a very friendly interface for generating XML content

Copyright 2005 Fourthought, Inc. (USA).
Detailed license and copyright information: http://4suite.org/COPYRIGHT
Project home, documentation, distributions: http://4suite.org/
"""

import sys
from Ft.Xml import XML_NAMESPACE,EMPTY_NAMESPACE,EMPTY_PREFIX,XMLNS_NAMESPACE
#from Ft.Xml import MessageSource

class MarkupWriter(object):
    """
    General-purpose utility class for generating XML (may eventually be
    expanded to produce more output types)

    Sample usage:
    
    from Ft.Xml import MarkupWriter
    writer = MarkupWriter(indent=u"yes")
    writer.startDocument()
    writer.startElement(u'xsa')
    writer.startElement(u'vendor')
    #Element with simple text (#PCDATA) content
    writer.simpleElement(u'name', content=u'Centigrade systems')
    #Note writer.text(content) still works
    writer.simpleElement(u'email', content=u"info@centigrade.bogus")
    writer.endElement(u'vendor')
    #Element with an attribute
    writer.startElement(u'product', attributes={u'id': u"100\u00B0"})
    #Note writer.attribute(name, value, namespace=None) still works
    writer.simpleElement(u'name', content=u"100\u00B0 Server")
    #XML fragment
    writer.xmlFragment('<version>1.0</version><last-release>20030401</last-release>')
    #Empty element
    writer.simpleElement(u'changes')
    writer.endElement(u'product')
    writer.endElement(u'xsa')
    writer.endDocument()

    Note on the difference between 4Suite writers and printers
    Writer  - module that exposes a broad public API for building output
              bit by bit
    Printer - module that simply takes a DOM and creates output from it
              as a whole, within one API invokation
    """
    def __init__(self, stream=sys.stdout, **wargs):
        """
        Convenience factory function for Markup writers (based on
        xsl:output in XSLT)
        """
        from Ft.Xml.Xslt.XmlWriter import XmlWriter
        from Ft.Xml.Xslt.OutputParameters import OutputParameters
        oparams = OutputParameters()
        for arg in wargs:
            setattr(oparams, arg, wargs[arg])
        self.writer = XmlWriter(oparams, stream)
        #self.__doc__ += self.writer.__doc__
        return

    def __getattr__(self, value):
        #Delegate to writer
        #if hasattr(self, value):
        #    return object.self.__dict, value)
        return getattr(self.writer, value)
        
    def startElement(self, tagName, namespace=EMPTY_NAMESPACE, extraNss=None,
                     attributes=None):
        """
        Create a start tag with optional attributes.  Must eventually
        be matched with an endElement call
        
        Note: all "strings" in these parameters must be unicode objects
        tagName - qualified name of the element (must be unicode)
        namespace - optional namespace URI
        attributes - optional dictionary mapping name to unicode value
                    the name can either be a unicode QName or a tuple
                    of (QName, namespace URI)
        extraNss - optional dictionary (defaults to an empty one) that
                   creates additional namespace declarations that the
                   user wants to place on the specific element. Each key
                   is a ns prefix, and each value a ns name (URI).
                   You do not need to use extraNss if you will be using
                   a similar namespace parameter.  In fact, most people
                   will never need this parameter.
        """
        if tagName.startswith('xml:'):
            #We can use such a raw test because of the very special case
            #nature of the XML prefix
            namespace = XML_NAMESPACE
        if namespace == EMPTY_NAMESPACE and u':' in tagName:
            #If they supplied a prefix, but not a namespace, complain
            #raise MarkupWriterException(MarkupWriterException.ELEM_PREFIX_WITHOUT_NAMESPACE)
            raise TypeError("Prefixed name %s specified without namespace.  Namespace should be provided in the second parameter."%(tagName))
        self.writer.startElement(tagName, namespace, extraNss)
        if attributes is not None:
            for name in attributes:
                if isinstance(name, tuple):
                    qname, namespace = name
                    value = attributes[name]
                    self.writer.attribute(qname, value, namespace)
                else:
                    if u':' in tagName:
                        #If they supplied a prefix, but not a namespace, complain
                        raise TypeError("Prefixed name %s specified without namespace.  Namespace should be provided by using the attribute name form (<qualified-name>, <namespace>)."%(name))
                    value = attributes[name]
                    self.writer.attribute(name, value)
        return

    def simpleElement(self, tagName, namespace=EMPTY_NAMESPACE, extraNss=None,
                      attributes=None, content=u""):
        """
        Create a simple tag with optional attributes and content.  The
        complete element, start tag, optional text content, end tag, will
        all be generated by this one call.  Must *not* be matched with
        an endElement call.

        Note: all "strings" in these parameters must be unicode objects
        tagName - qualified name of the element
        namespace - optional namespace URI
        attributes - optional dictionary mapping name to unicode value
                    the name can either be a unicode QName or a tuple
                    of (QName, namespace URI)
        content   - optional unicode object with the text body of the
                    simple element
        extraNss - optional dictionary (defaults to an empty one) that
                   creates additional namespace declarations that the
                   user wants to place on the specific element. Each key
                   is a ns prefix, and each value a ns name (URI).
                   You do not need to use extraNss if you will be using
                   a similar namespace parameter.  In fact, most people
                   will never need this parameter.
        """
        if tagName.startswith('xml:'):
            #We can use such a raw test because of the very special case
            #nature of the XML prefix
            namespace = XML_NAMESPACE
        self.startElement(tagName, namespace, extraNss, attributes)
        if content:
            self.writer.text(content)
        self.writer.endElement(tagName, namespace)
        return

    def xmlFragment(self, fragment):
        """
        Incorporate a well-formed general entity into the output.
        fragment of
        fragment - string (must not be a Unicode object) to be incorporated
                   verbatim into the output, after testing for wellp-formedness
        """
        from Ft.Xml.Domlette import EntityReader
        #Essentially just a WF test.
        #We don't actually use the resulting docfrag
        docfrag = EntityReader.parseString(
            fragment, 'urn:bogus:Ft.Xml.Xslt.MarkupWriter.xmlFragment')
        self.writer._stream.write(fragment)
        return


## from Ft import FtException
## class MarkupWriterException(FtException):
##     """
##     Exception class for errors specific to MarkupWriter
##     """
##     ELEM_PREFIX_WITHOUT_NAMESPACE = 100
##     ATTR_PREFIX_WITHOUT_NAMESPACE = 100

##     def __init__(self, errorCode, *args):
##         FtException.__init__(self, errorCode, MessageSource.MARKUPWRITER, args)
##         return


www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.