Changeset 3083:e30c5d8f1a34 in livinglogic.python.xist

Show
Ignore:
Timestamp:
12/27/07 17:31:58 (12 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

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

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • HOWTO.xml

    r2944 r3083  
    121121</prog> 
    122122</example> 
     123 
     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> 
     129<prog> 
     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        +html.li("I hear and I forget.") 
     135        +html.li("I see and I believe.") 
     136        +html.li("I do and I understand.") 
     137</prog> 
     138</example> 
     139 
    123140</section> 
    124141 
     
    128145provides several functions:</par> 
    129146<prog> 
    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) 
     153</prog> 
    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 
    149159 
    150 node = parsers.parseString( 
     160node = parsers.parsestring( 
    151161    "&lt;p&gt;Hello &lt;a href='http://www.python.org/'&gt;Python&lt;/a&gt; world!&lt;/p&gt;" 
    152162) 
     
    154164</example> 
    155165 
    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> 
    159169</section> 
    160170</section> 
     
    377387have a <lit>class</lit> attribute.</par> 
    378388 
     389<par>Also &xml; attributes can be accessed as Python attributes of the 
     390<lit>attrs</lit> object:</par> 
     391 
     392<prog> 
     393node = html.div(u"foo", class_="bar") 
     394print node.attrs.class_ 
     395</prog> 
    379396 
    380397<section><title>Defining attributes</title> 
     
    529546</section> 
    530547 
    531 <section><title>Namespaces</title> 
     548<section><title>Namespaces and pools</title> 
    532549 
    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> 
    536  
    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> 
    542  
    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> 
     554 
     555<example><title>Assigning a namespace to elements</title> 
     556<prog> 
     557from ll.xist import xsc, parsers 
     558from ll.xist.ns import html 
     559 
     560xmlns = "http://xmlns.example.org/foo" 
     561 
    554562class python(xsc.Element): 
     563    xmlns = xmlns 
     564 
    555565    def convert(self, converter): 
    556         return html.a( 
    557             u"Python", 
    558             href=u"http://www.python.org/" 
    559         ) 
     566        return html.a(u"Python", href=u"http://www.python.org/") 
    560567 
    561568class cool(xsc.Element): 
     569    xmlns = xmlns 
     570 
    562571    def convert(self, converter): 
    563572        node = html.b(self.content, u" is cool!") 
    564573        return node.convert(converter) 
    565  
    566 class __ns__(xsc.Namespace): 
    567     xmlname = "foo" 
    568     xmlurl = "http://www.example.com/foo" 
    569 __ns__.update(vars()) 
    570 </prog> 
    571 </example> 
    572  
    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> 
    575  
    576 <section><title>Namespaces as modules</title> 
    577  
    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> 
    584  
    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"http://www.python.org/" 
    592         ) 
    593  
    594 class cool(xsc.Element): 
    595     def convert(self, converter): 
    596         node = html.b(self.content, u" is cool!") 
    597         return node.convert(converter) 
    598  
    599 class __ns__(xsc.Namespace): 
    600     xmlname = "foo" 
    601     xmlurl = "http://www.example.com/foo" 
    602 __ns__.<em>makemod</em>(vars()) 
    603 </prog> 
    604 </example> 
    605  
    606 <par>Suppose that the above code is in the file <filename>foo.py</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"http://www.example.com/foo" with 2 elements from "foo.py" at 0x87654321&gt; 
    613 <prompt>&gt;&gt;&gt; </prompt><input>foo.python</input> 
    614 &lt;foo:python element at 0x87654321&gt; 
    615 </tty> 
     574</prog> 
     575</example> 
     576 
     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> 
     579 
     580<example><title>Putting elements in a pool</title> 
     581<prog> 
     582pool = xsc.Pool(python, cool) 
     583</prog> 
     584</example> 
     585 
     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> 
     588 
     589<example><title>Populating a pool with a <lit>with</lit> block</title> 
     590<prog> 
     591from __future__ import with_statement 
     592 
     593from ll.xist import xsc, parsers 
     594from ll.xist.ns import html 
     595 
     596with xsc.Pool() as pool: 
     597    xmlns = "http://xmlns.example.org/foo" 
     598 
     599    class python(xsc.Element): 
     600        xmlns = xmlns 
     601 
     602        def convert(self, converter): 
     603            return html.a(u"Python", href=u"http://www.python.org/") 
     604 
     605    class cool(xsc.Element): 
     606        xmlns = xmlns 
     607 
     608        def convert(self, converter): 
     609            node = html.b(self.content, u" is cool!") 
     610            return node.convert(converter) 
     611</prog> 
     612</example> 
     613 
     614<par>Now you can use this pool for parsing:</par> 
     615 
     616<example><title>Parsing &xml;</title> 
     617<prog><![CDATA[ 
     618input = '<cool xmlns="http://xmlns.example.org/foo"><python/></cool>' 
     619 
     620node = parsers.parsestring(input, pool=pool) 
     621]]></prog> 
     622</example> 
     623 
     624<par>It's also possible to call the parsing function with a predefined mapping 
     625between namespace names and namespace prefixes:</par> 
     626 
     627<example><title>Parsing &xml; with predefined prefix mapping</title> 
     628<prog><![CDATA[ 
     629input = '<cool><python/></cool>' 
     630 
     631node = parsers.parsestring(input, pool=pool, prefixes={None: "http://xmlns.example.org/foo"}) 
     632]]></prog> 
     633</example> 
     634 
     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> 
     638 
     639<example><title>Registering modules in a pool</title> 
     640<prog> 
     641import foo_xmlns # This is the module containing the element classes 
     642 
     643pool = xsc.Pool(foo_xmlns) 
     644</prog> 
     645</example> 
     646 
    616647</section> 
    617648 
     
    958989</section> 
    959990 
    960 </section> 
    961991 
    962992<section><title>Publishing &xml; trees</title>