Changeset 3083:e30c5d8f1a34 in livinglogic.python.xist

12/27/07 17:31:58 (12 years ago)
Walter Doerwald <walter@…>

Update HOWTO.xml to the new way of handling namespaces and parsing.

1 modified


  • HOWTO.xml

    r2944 r3083  
     124<par>Furthermore it's possible to use <lit>with</lit> blocks to construct 
     125&xist; trees. Inside a <lit>with</lit> block the unary <lit>+</lit> operator 
     126or the <function>add</function> function can be used to add nodes or attributes 
     127to the current level of the tree:</par> 
     128<example><title>Using <lit>with</lit> blocks</title> 
     130with html.div(class_="quote") as node: 
     131    with html.h1("Confucius (551-479 BC)"): 
     132        xsc.add(class_="author") 
     133    with html.ol(): 
     134"I hear and I forget.") 
     135"I see and I believe.") 
     136"I do and I understand.") 
    128145provides several functions:</par> 
    130 def parseString(text, base=None, sysid=None, **parserargs) 
    131 def parseURL(url, base=None, sysid=None, **parserargs) 
    132 def parseFile(filename, base=None, sysid=None, **parserargs) 
    133 def parse(stream, base=None, sysid=None, **parserargs) 
    134 </prog> 
    135 <par><pyref module="ll.xist.parsers" function="parseString"><function>parseString</function></pyref> 
    136 is for parsing strings (<class>str</class> and <class>unicode</class>) and 
    137 <pyref module="ll.xist.parsers" function="parseURL"><function>parseURL</function></pyref> is for 
    138 parsing resources from &url;s. With 
    139 <pyref module="ll.xist.parsers" function="parseFile"><function>parseFile</function></pyref> 
    140 you can parse local files and with <pyref module="ll.xist.parsers" function="parse"><function>parse</function></pyref> 
    141 you can directly parse from a file-like object.</par> 
    142 <par>All four functions create a parser internally, parse the supplied source document and 
    143 return the resulting object tree.</par> 
     147def parsestring(data, base=None, encoding=None, **builderargs) 
     148def parseiter(iterable, base=None, encoding=None, **builderargs) 
     149def parsestream(stream, base=None, encoding=None, bufsize=8192, **builderargs) 
     150def parsefile(filename, base=None, encoding=None, bufsize=8192, **builderargs) 
     151def parseurl(name, base=None, encoding=None, bufsize=8192, headers=None, data=None, **builderargs) 
     152def parseetree(tree, base=None, **builderargs) 
    144154<par>For example, parsing a string can be done like this:</par> 
    145155<example><title>Parsing a string</title> 
    148158from ll.xist.ns import html 
    150 node = parsers.parseString( 
     160node = parsers.parsestring( 
    151161    "&lt;p&gt;Hello &lt;a href=''&gt;Python&lt;/a&gt; world!&lt;/p&gt;" 
    156 <par>For further info about the rest of the arguments to the parsing 
    157 functions, see the documentation for 
    158 <pyref module="ll.xist.parsers" class="Parser"><class>ll.xist.parsers.Parser</class></pyref>.</par> 
     166<par>For further info about the arguments to the parsing functions, see the 
     167documentation for 
     168<pyref module="ll.xist.parsers" class="Builder"><class>ll.xist.parsers.Builder</class></pyref>.</par> 
    377387have a <lit>class</lit> attribute.</par> 
     389<par>Also &xml; attributes can be accessed as Python attributes of the 
     390<lit>attrs</lit> object:</par> 
     393node = html.div(u"foo", class_="bar") 
     394print node.attrs.class_ 
    380397<section><title>Defining attributes</title> 
    531 <section><title>Namespaces</title> 
     548<section><title>Namespaces and pools</title> 
    533550<par>Now that you've defined your own elements, you have to tell the parser 
    534 about them, so they can be instantiated when a file is parsed. This is done 
    535 with namespace classes.</par> 
    537 <par>Namespace classes can be thought of as object oriented versions of 
    538 &xml; namespaces. Two class attributes can be used to configure the namespace: 
    539 <lit>xmlname</lit> specifies the default namespace prefix to use for the 
    540 namespace and <lit>xmlurl</lit> is the namespace name. All element classes 
    541 nested inside the namespace class belong to the namespace.</par> 
    543 <par>It's also possible to define your namespace class without any nested 
    544 element classes and later add those classes to the namespace by attribute 
    545 assignment or with the class method 
    546 <pyref module="ll.xist.xsc" class="Namespace" method="update"><method>update</method></pyref>, 
    547 which expects a dictionary as an argument. All objects found in the values of 
    548 the dictionary will be added to the namespace as attributes. So you can put the 
    549 namespace class at the end of your Python module after all the element classes 
    550 are defined and add all the objects from the local scope to the namespace. Your 
    551 complete namespace might looks like this:</par> 
    552 <example><title>Defining and populating a namespace</title> 
    553 <prog> 
     551about them, so they can be instantiated when a file is parsed. First you have to 
     552assign an &xml; namespace to these classes. This is done by setting the class 
     553attribute <lit>xmlns</lit> to the namespace name:</par> 
     555<example><title>Assigning a namespace to elements</title> 
     557from ll.xist import xsc, parsers 
     558from ll.xist.ns import html 
     560xmlns = "" 
    554562class python(xsc.Element): 
     563    xmlns = xmlns 
    555565    def convert(self, converter): 
    556         return html.a( 
    557             u"Python", 
    558             href=u"" 
    559         ) 
     566        return html.a(u"Python", href=u"") 
    561568class cool(xsc.Element): 
     569    xmlns = xmlns 
    562571    def convert(self, converter): 
    563572        node = html.b(self.content, u" is cool!") 
    564573        return node.convert(converter) 
    566 class __ns__(xsc.Namespace): 
    567     xmlname = "foo" 
    568     xmlurl = "" 
    569 __ns__.update(vars()) 
    570 </prog> 
    571 </example> 
    573 <par>All defined namespace classes will be registered with the parser automatically, 
    574 so all elements belonging to the namespace will be used when parsing files.</par> 
    576 <section><title>Namespaces as modules</title> 
    578 <par>It is convenient to define all classes that belong to one namespace in one 
    579 Python module. However this means that the resulting module will only contain 
    580 one <z>interesting</z> object: the namespace class. To make using this class 
    581 more convenient, it's possible to turn the namespace class into a module by 
    582 using the class method <pyref module="ll.xist.xsc" class="Namespace" method="makemod"><method>makemod</method></pyref> 
    583 instead of <method>update</method>:</par> 
    585 <example><title>Turning a namespace into a module</title> 
    586 <prog> 
    587 class python(xsc.Element): 
    588     def convert(self, converter): 
    589         return html.a( 
    590             u"Python", 
    591             href=u"" 
    592         ) 
    594 class cool(xsc.Element): 
    595     def convert(self, converter): 
    596         node = html.b(self.content, u" is cool!") 
    597         return node.convert(converter) 
    599 class __ns__(xsc.Namespace): 
    600     xmlname = "foo" 
    601     xmlurl = "" 
    602 __ns__.<em>makemod</em>(vars()) 
    603 </prog> 
    604 </example> 
    606 <par>Suppose that the above code is in the file <filename></filename>. 
    607 Doing an <lit>import foo</lit> will then give you the namespace class instead 
    608 of the module:</par> 
    609 <tty> 
    610 <prompt>&gt;&gt;&gt; </prompt><input>import foo</input> 
    611 <prompt>&gt;&gt;&gt; </prompt><input>foo</input> 
    612 &lt;foo:__ns__ namespace name=u"foo" url=u"" with 2 elements from "" at 0x87654321&gt; 
    613 <prompt>&gt;&gt;&gt; </prompt><input>foo.python</input> 
    614 &lt;foo:python element at 0x87654321&gt; 
    615 </tty> 
     577<par>When parsing the parser fetches the classes it uses from a <class>Pool</class> 
     578object. We can put our two classes into a pool like this:</par> 
     580<example><title>Putting elements in a pool</title> 
     582pool = xsc.Pool(python, cool) 
     586<par>It's also possible to register the element classes in a pool directly at 
     587class construction time via a <lit>with</lit> block like this:</par> 
     589<example><title>Populating a pool with a <lit>with</lit> block</title> 
     591from __future__ import with_statement 
     593from ll.xist import xsc, parsers 
     594from ll.xist.ns import html 
     596with xsc.Pool() as pool: 
     597    xmlns = "" 
     599    class python(xsc.Element): 
     600        xmlns = xmlns 
     602        def convert(self, converter): 
     603            return html.a(u"Python", href=u"") 
     605    class cool(xsc.Element): 
     606        xmlns = xmlns 
     608        def convert(self, converter): 
     609            node = html.b(self.content, u" is cool!") 
     610            return node.convert(converter) 
     614<par>Now you can use this pool for parsing:</par> 
     616<example><title>Parsing &xml;</title> 
     618input = '<cool xmlns=""><python/></cool>' 
     620node = parsers.parsestring(input, pool=pool) 
     624<par>It's also possible to call the parsing function with a predefined mapping 
     625between namespace names and namespace prefixes:</par> 
     627<example><title>Parsing &xml; with predefined prefix mapping</title> 
     629input = '<cool><python/></cool>' 
     631node = parsers.parsestring(input, pool=pool, prefixes={None: ""}) 
     635<par>If you have many elements, registering them in a pool becomes cumbersome. 
     636In this case you can put your element classes into a module and then 
     637register the module in the pool:</par> 
     639<example><title>Registering modules in a pool</title> 
     641import foo_xmlns # This is the module containing the element classes 
     643pool = xsc.Pool(foo_xmlns) 
    960 </section> 
    962992<section><title>Publishing &xml; trees</title>