Dare's XLINQ examples in Amara

Dare's examples for XLINQ are interesting. They are certainly more streamlined than the usual C# and Java fare I see, but still a bit clunky compared to what I'm used to in Python. To be fair a lot of that is on the C# language, so I'd be interested in seeing what XLINK looks like from Python.NET or Boo.

The following is my translation from Dare's fragments into corresponding Amara fragments (compatible with the Amara 1.2 branch).

'1. Creating an XML document'

import amara
#Done in 2 chunks just to show the range of options
#Another way would be to start with amara.create_document
skel = '<!--XLinq Contacts XML Example--><?MyApp 123-44-4444?><contacts/>'
doc = amara.parse(skel)
doc.contacts.xml_append_fragment("""<contact>
  <name>Patrick Hines</name>
  <phone>206-555-0144</phone>
  <address>
    <street1>123 Main St</street1>
    <city>Mercer Island</city>
    <state>WA</state>
    <postal>68042</postal>
  </address>
</contact>
""")

'2. Creating an XML element in the "http://example.com" namespace'

doc.xml_create_element(u'contacts', u'http://example.com')

'3. Loading an XML element from a file'

amara.parse_path('c:\myContactList.xml')

'4. Writing out an array of Person objects as an XML file'

persons = {}
persons[u'Patrick Hines'] = [u'206-555-0144', u'425-555-0145']
persons[u'Gretchen Rivas'] = [u'206-555-0163']
doc.xml_create_element(u'contacts')
for name in persons:
    doc.contacts.xml_append_fragment('<person><name>%s</name></person>'%name)
    for phone in persons[name]:
        doc.contacts.person[-1].xml_append_fragment('<phone>%s</phone>'%phone)
print doc.xml()

'5. Print out all the element nodes that are children of the <contact> element'

for c in contact.xml_child_elements():
    print c.xml()

'6. Print all the <phone> elements that are children of the <contact> element'

for c in contact.xml_xpath(u'phone'):
    print c.xml()

'7. Adding a <phone> element as a child of the <contact> element'

contacts.xml_append_fragment('<phone>%s</phone>'%'206-555-0168')

'8. Adding a <phone> element as a sibling of another <phone> element'

mobile = contacts.xml_create_element(u'phone', content=u'206-555-0168')
first = contacts.phone
contacts.xml_insert_after(first, mobile)

'9. Adding an <address> element as a child of the <contact> element'

contacts.xml_append_fragment("""  <address>
    <street1>123 Main St</street1>
    <city>Mercer Island</city>
    <state>WA</state>
    <postal>68042</postal>
  </address>
""")

'10. Deleting all <phone> elements under a <contact> element'

for p in contact.phone: contact.xml_remove_child(p)

'11. Delete all children of the <address> element which is a child of the <contact> element'

contacts.contact.address.xml_clear()

'12. Replacing the content of the <phone> element under a <contact> element'

#Not really necessary: just showing how to clear the content
contact.phone.xml_clear()
contact.phone = u'425-555-0155'

'13. Alternate technique for replacing the content of the <phone> element under a <contact> element'

contact.phone = u'425-555-0155'

'14. Creating a contact element with attributes multiple phone number types'

#I'm sure it's clear by now how easy this would be with xml_append_fragment
#So here is the more analogous API approach
contact = contacts.xml_create_element(u'contact')
contact.xml_append(contact.xml_create_element(u'name', content=u'Patrick Hines'))
contact.xml_append(
    contact.xml_create_element(u'phone',
                               attributes={u'type': u'home'},
                               content=u'206-555-0144'))
contact.xml_append(
    contact.xml_create_element(u'phone',
                               attributes={u'type': u'work'},
                               content=u'425-555-0145'))

'15. Printing the value of the <phone> element whose type attribute has the value "home"'

print u'Home phone is:', contact.xml_xpath(u'phone[@type="home"]')

'16. Deleting the type attribute of the first <phone> element under the <contact> element'

del contact.phone.type

'17. Transforming our original <contacts> element to a new <contacts> element containing a list of <contact> elements whose children are <name> and <phoneNumbers>'

new_contacts = doc.xml_create_element(u'contacts')
for c in doc.contacts.contact:
    new_contacts.xml_append_fragment('''<contact>
    <name>%s</name>
    <phoneNumbers/>
    </contact>'''%c.name)
    for p in c.phone:
        new_contacts.phoneNumbers.xml_append(p)

'18. Retrieving the names of all the contacts from Washington, sorted alphabetically '

wash_contacts = contacts.xml_xpath(u'contact[address/state="WA"]')
names = [ unicode(c.name) for c in contacts.contact ]
names.sort()

[Uche Ogbuji]

via Copia