Entrian Solutions
By the same author: 

Are you a professional Visual Studio developer?

Then you should check out Entrian Source Search:


Entrian Source Search is a powerful search addin for Visual Studio.

It displays syntax colored search results within a fraction of a second, whether you're working with hundreds of lines of code or millions.

It's the fastest and easiest way to navigate your source code.

Learn more...

PyMeld Reference

class ReadOnlyError(Exception)

Raised if you try to modify a readonly Meld object.

class Meld()

Represents an XML document, or a fragment of one. Pass XML/XHTML source to the constructor. You can then access all the elements with id="name" attributes as object.name, and all the attributes of the outermost element as object.attribute.

def __init__(self, source, readonly=False, replaceUnderscoreWithDash=False)

Creates a Meld from XML source. readonly does what it says. replaceUnderscoreWithDash lets you write code like this:

>>> html = '<html><div id="header-box">xxx</div></html>'
>>> meld = Meld(html, replaceUnderscoreWithDash=True)
>>> meld.header_box = "Yay!"
>>> print meld.header_box
<div id="header-box">Yay!</div>
>>> del meld.header_box
>>> print meld

def __getattr__(self, name)

object.<name>, if this Meld contains an element with an id attribute of name, returns a Meld representing that element.

Otherwise, object.<name> returns the value of the attribute with the given name, as a string. If no such attribute exists, an AttributeError is raised.

object._content returns the content of the Meld, not including the enclosing <element></element>, as a string.

>>> p = Meld('<p style="one">Hello <b id="who">World</b></p>')
>>> print p.who
<b id="who">World</b>
>>> print p.style
>>> print p._content
Hello <b id="who">World</b>
>>> print p.who._content

def __setattr__(self, name, value)

object.<name> = value sets the XML content of the element with an id of name, or if no such element exists, sets the value of the name attribute on the outermost element. If the attribute is not already there, a new attribute is created.

>>> p = Meld('<p style="one">Hello <b id="who">World</b></p>')
>>> p.who = "Richie"
>>> p.style = "two"
>>> p.align = "center"
>>> p.who.id = "newwho"
>>> print p
<p align="center" style="two">Hello <b id="newwho">Richie</b></p>

def __delattr__(self, name)

Deletes the named element or attribute from the Meld:

>>> p = Meld('<p style="one">Hello <b id="who">World</b></p>')
>>> del p.who
>>> del p.style
>>> print p
<p>Hello </p>

def __mod__(self, values)

object % value, object % sequence, or object % dictionary all mimic the % operator for strings:

>>> xml = '<x><y id="greeting">Hello</y> <z id="who">World</z></x>'
>>> x = Meld(xml)
>>> print x % ("Howdy", "everybody")
<x><y id="greeting">Howdy</y> <z id="who">everybody</z></x>
>>> print x % {'who': 'all'}
<x><y id="greeting">Hello</y> <z id="who">all</z></x>

Assignment for sequences happens in the same order that nodes with 'id' attributes appear in the document, not including the top-level node (because if the top-level node were included, you'd only ever be able to assign to that and nothing else):

>>> xml = '''<a id="a">
... <b>  <!-- `b` has no ID, hence is ignored. -->
...     <c id="c">First one</c>
...     <d id="d">Second one</d>
... </b>
... <e id="e">Third one; the content includes 'f':
...     <f id="f">Removed when 'e' is assigned to</f>
... </e>
... </a>'''
>>> a = Meld(xml)
>>> print a % ('One, with a <z id="new">new</z> node', 'Two', 'Three')
<a id="a">
<b>  <!-- `b` has no ID, hence is ignored. -->
    <c id="c">One, with a <z id="new">new</z> node</c>
    <d id="d">Two</d>
<e id="e">Three</e>

Giving the wrong number of elements to % raises the same exceptions as the builtin string % operator. Unlike the builtin % operator, dictionaries don't need to specify all the keys:

>>> print x % "Howdy"
Traceback (most recent call last):
TypeError: not enough arguments
>>> print x % ("Howdy", "everybody", "everywhere")
Traceback (most recent call last):
TypeError: not all arguments converted
>>> print x % {"greeting": "Howdy"}
<x><y id="greeting">Howdy</y> <z id="who">World</z></x>

def toFormatString(self, useDict=False)

Converts a Meld object to a string, with the contents of any tags with id attributes replaced with %s or %(id)s. This lets you use Python's built-in % operator rather than PyMeld's, which can speed things up considerably when you're looping over a lot of data. Here's the example from the main documentation, speeded up by using toFormatString() and by avoiding repeated use of the += operator:

>>> xhtml = '''<html><table id="people">
... <tr id="header"><th>Name</th><th>Age</th></tr>
... <tr id="row"><td id="name">Example</td><td id="age">21</td></tr>
... </table></html>'''
>>> doc = Meld(xhtml)
>>> rowFormat = doc.row.toFormatString()
>>> rows = []
>>> for name, age in [("Richie", 30), ("Dave", 39), ("John", 78)]:
...      rows.append(rowFormat % (name, age))
>>> doc.people = '\n' + doc.header + ''.join(rows)
>>> print re.sub(r'</tr>\s*', '</tr>\n', str(doc))  # Prettify
<html><table id="people">
<tr id="header"><th>Name</th><th>Age</th></tr>
<tr id="row"><td id="name">Richie</td><td id="age">30</td></tr>
<tr id="row"><td id="name">Dave</td><td id="age">39</td></tr>
<tr id="row"><td id="name">John</td><td id="age">78</td></tr>

So the inner loop no longer contains any PyMeld calls at all - it only manipulates strings and lists. Here's what doc.row.toFormatString() actually returns - note that this is a string, not a PyMeld object:

>>> print doc.row.toFormatString()
<tr id="row"><td id="name">%s</td><td id="age">%s</td></tr>

You can ask for a format string that expects a dictionary rather than a tuple using the useDict parameter:

>>> print doc.row.toFormatString(useDict=True)
<tr id="row"><td id="name">%(name)s</td><td id="age">%(age)s</td></tr>

If your markup contains % symbols, they are correctly quoted in the resulting format string:

>>> doc = Meld("<html><p>10% <span id='drink'>gin</span>.</p></html>")
>>> print doc.toFormatString()
<html><p>10%% <span id='drink'>%s</span>.</p></html>
>>> print doc.toFormatString() % 'vodka'
<html><p>10% <span id='drink'>vodka</span>.</p></html>

def clone(self, readonly=0, replaceUnderscoreWithDash=False)

Creates a clone of a Meld, for instance to change an attribute without affecting the original document:

>>> p = Meld('<p style="one">Hello <b id="who">World</b></p>')
>>> q = p.clone()
>>> q.who = "Richie"
>>> print q.who
<b id="who">Richie</b>
>>> print p.who
<b id="who">World</b>

def __add__(self, other)

object1 + object2 turns both objects into strings and returns the concatenation of the strings:

>>> a = Meld('<html><span id="x">1</span></html>')
>>> b = Meld('<html><span id="y">2</span></html>')
>>> c = Meld('<html><span id="z">3</span></html>')
>>> print a + b
<html><span id="x">1</span></html><html><span id="y">2</span></html>
>>> print a.x + b.y + c.z
<span id="x">1</span><span id="y">2</span><span id="z">3</span>

def __radd__(self, other)

See __add__

def __iadd__(self, other)

object1 += object2 appends a string or a clone of a Meld to the end of another Meld's content. This is used to build things like HTML tables, which are collections of other objects (eg. table rows). See Real-world example in the main documentation.

def __str__(self)

Returns the XML that this Meld represents. Don't call this directly - instead convert a Meld to a string using str(object). print does this automatically, which is why none of the examples calls str.

def __unicode__(self)

Returns the XML that this Meld represents. Don't call this directly - instead convert a Meld to unicode using unicode(object). print does this automatically, which is why none of the examples calls str. Note that PyMeld's ability to handle Unicode is largely untested.

def test()

Tests the PyMeld module, performing code coverage analysis if Entrian.Coverage is available. Returns (failed, total), a la doctest.testmod.