local xml = require 'pl.xml' local asserteq = require 'pl.test'.asserteq local dump = require 'pl.pretty'.dump -- Prosody stanza.lua style XML building d = xml.new 'top' : addtag 'child' : text 'alice' : up() : addtag 'child' : text 'bob' d = xml.new 'children' : addtag 'child' : addtag 'name' : text 'alice' : up() : addtag 'age' : text '5' : up() : addtag('toy',{type='fluffy'}) : up() : up() : addtag 'child': addtag 'name' : text 'bob' : up() : addtag 'age' : text '6' : up() : addtag('toy',{type='squeaky'}) asserteq( xml.tostring(d,'',' '), [[ alice 5 bob 6 ]]) -- Orbit-style 'xmlification' local children,child,toy,name,age = xml.tags 'children, child, toy, name, age' d1 = children { child {name 'alice', age '5', toy {type='fluffy'}}, child {name 'bob', age '6', toy {type='squeaky'}} } assert(xml.compare(d,d1)) -- or we can use a template document to convert Lua data to LOM templ = child {name '$name', age '$age', toy{type='$toy'}} d2 = children(templ:subst{ {name='alice',age='5',toy='fluffy'}, {name='bob',age='6',toy='squeaky'} }) assert(xml.compare(d1,d2)) -- Parsing Google Weather service results -- local joburg = [[ ]] -- we particularly want to test the built-in XML parser here, not lxp.lom local function parse (str) return xml.parse(str,false,true) end local d = parse(joburg) function match(t,xpect) local res,ret = d:match(t) asserteq(res,xpect,0,1) ---> note extra level, so we report on calls to this function! end t1 = [[ ]] match(t1,{ condition = "Clear", temp = "24", } ) t2 = [[ {{ }} ]] local conditions = { { low = "60", high = "89", day = "Sat", condition = "Clear", }, { low = "53", high = "86", day = "Sun", condition = "Clear", }, { low = "57", high = "87", day = "Mon", condition = "Clear", }, { low = "60", high = "84", day = "Tue", condition = "Clear", } } match(t2,conditions) config = [[ 1.3 10 bozo ]] d,err = parse(config) if not d then print(err); os.exit(1) end -- can match against wildcard tag names (end with -) -- can be names match([[ {{$value}} ]],{ {key="alpha", value = "1.3"}, {key="beta", value = "10"}, {key="name",value = "bozo"}, }) -- can be numerical indices match([[ {{<1->$2}} ]],{ {"alpha","1.3"}, {"beta","10"}, {"name","bozo"}, }) -- _ is special; means 'this value is key of captured table' match([[ {{<_->$1}} ]],{ alpha = {"1.3"}, beta = {"10"}, name = {"bozo"}, }) -- the numerical index 0 is special: a capture of {[0]=val} becomes simply the value val match([[ {{<_->$0}} ]],{ alpha = "1.3", name = "bozo", beta = "10" }) -- this can of course also work with attributes, but then we don't want to collapse! config = [[ 1.3 10 bozo ]] d,err = parse(config) if not d then print(err); os.exit(1) end match([[ {{<_- type='$1'>$2}} ]],{ alpha = {"number","1.3"}, beta = {"number","10"}, name = {"string","bozo"}, }) d,err = parse [[ ]] if not d then print(err); os.exit(1) end --xml.debug = true res,err = d:match [[ {{}} ]] asserteq(res,{ HOST = "windows-unknown-linux-gnu", COPYRIGHT = "Copyright (C) 1999-2009 ImageMagick Studio LLC", NAME = "ImageMagick", LIB_VERSION = "0x651", VERSION = "6.5.1", RELEASE_DATE = "2009-05-01", WEBSITE = "http://www.imagemagick.org", LIB_VERSION_NUMBER = "6,5,1,3", CC = "vs7", DELEGATES = "bzlib freetype jpeg jp2 lcms png tiff x11 xml wmf zlib" }) -- short excerpt from -- /usr/share/mobile-broadband-provider-info/serviceproviders.xml d = parse [[ Cell-c Cellcis 196.7.0.138 196.7.142.132 MTN 196.11.240.241 209.212.97.1 Vodacom 196.207.40.165 196.43.46.190 Unrestricted 196.207.32.69 196.43.45.190 Virgin Mobile 196.7.0.138 196.7.142.132 ]] res = d:match [[ {{ {{ $0 }} }} ]] asserteq(res,{ za = { "Cell-c", "MTN", "Vodacom", "Virgin Mobile" } }) res = d:match [[ $name 196.43.46.190 ]] asserteq(res,{ name = "Vodacom", country = "za", apn = "internet" }) d = parse[[ XXX YYY 1 ]] match([[ {{ $_ $0 }} ]],{XXX = '',YYY = '1'}) -- can always use xmlification to generate your templates... local SP, country, provider, gsm, apn, dns = xml.tags 'serviceprovider, country, provider, gsm, apn, dns' t = SP{country{code="$country",provider{ name '$name', gsm{apn {value="$apn",dns '196.43.46.190'}} }}} out = xml.tostring(t,' ',' ') asserteq(out,[[ $name 196.43.46.190 ]]) ----- HTML is a degenerate form of XML ;) -- attribute values don't need to be quoted, tags are case insensitive, -- and some are treated as self-closing doc = xml.parsehtml [[ Hello dolly
HTML is slack
]] asserteq(xml.tostring(doc),[[ Hello dolly
HTML is slack
]]) doc = xml.parsehtml [[ ]] asserteq(xml.tostring(doc),"") -- note that HTML mode currently barfs if there isn't whitespace around things -- like '<' and '>' in scripts. doc = xml.parsehtml [[

hello dammit

]] script = doc:get_elements_with_name 'script' asserteq(script[1]:get_text(), 'function less(a,b) { return a < b; }') -- test attribute order local test_attrlist = xml.new('AttrList',{ Attr3="Value3", ['Attr1'] = "Value1", ['Attr2'] = "Value2", [1] = 'Attr1', [2] = 'Attr2', [3] = 'Attr3' }) asserteq( xml.tostring(test_attrlist), "" ) -- commments str = [[ dolly ]] doc = parse(str) asserteq(xml.tostring(doc),[[ dolly ]]) -- underscores and dashes in attributes str = [[ dolly ]] doc = parse(str) print(doc) print(xml.tostring(doc)) asserteq(xml.tostring(doc),[[ dolly]])