<div>Using erlsom, you can write:</div>
<div>
<p><font face="courier new,monospace">-module(product).<br>-compile(export_all).</font></p>
<p><font face="courier new,monospace">parse(File) -><br>  {ok, Model} = erlsom:compile_xsd_file("product.xsd"),<br>  {ok, Result, _} = erlsom:scan_file(File, Model),<br>  Result.<br></font></p></div>
<div>Then you can do:</div>
<div>1> erlsom:write_xsd_hrl_file("product.xsd", "product.hrl", []).</div>
<div>2> rr("product.hrl"). </div>
<div>3> product:parse("export.xml").                          <br>#'Export'{anyAttribs = [],<br>          'Product' = #'Product'{anyAttribs = [],<br>                                 'SKU' = "403276",
<br>                                 'ItemName' = "Trivet",<br>                                 'CollectionNo' = 0,<br>                                 'Pages' = 0}}   </div>
<div> </div>
<div>Very different from the example, but also nice :) And maybe more useful, depending on what you want to do with it.</div>
<div> </div>
<div>You need to provide a schema, of course. I am pasting an example schema for this XML at the end of this email. Using the schema has the advantage that the xml document will be validated. Having a schema is useful as well to document the interface. Even if you don't like XML schema's (I still have problems with them, even after writing the parser), having a specification should be a good thing. Isn't this a bit like 
ASN.1, actually?</div>
<div> </div>
<div>If you don't like the approach with the schema, you can also do this:</div>
<div> </div>
<div><font face="courier new,monospace">-module(product_sax).</font><font face="courier new,monospace"><br>-compile(export_all).</font></div>
<div>
<p><font face="courier new,monospace">parse(File) -><br>  {ok, Bin}  = file:read_file(File),<br>  {R, _} = erlsom_sax:parseDocument(binary_to_list(Bin), {s1, []}, <br>                                    fun callback/2),
<br>  lists:reverse(R).</font></p>
<p><font face="courier new,monospace">callback({startElement, _, "Product", _, _}, {s1, S}) -> <br>  {s2, S};<br>callback({startElement, _, Tag, _, _}, {s2, S}) -> <br>  {s3, {Tag, S}};<br>callback({characters, Value}, {s3, {Tag, List}}) -> 
<br>  {s2, [{Tag, Value} | List]};<br>callback({endElement, _, "Product", _}, {_, S}) -> S;<br>callback(_, S) -> S.</font></p></div>
<div>4> product_sax:parse("export.xml").                            <br>[{"SKU","403276"},{"ItemName","Trivet"},{"CollectionNo","0"},{"Pages","0"}]
</div>
<div> </div>
<div>Using a callback and a simple sort of state machine - also nice, and very efficient.</div>
<div> </div>
<div>I have written a new version of the sax parser that can parse a file in blocks, so that you can use it to parse very big files or streams of data. At the moment I am doing some final testing, finishing the documentation etc. Not the kind of work I like, so it is likely to take a while (1 - 2 weeks). The new release also fixes some bugs in the XML Schema related code, and it has some features that should improve the capabilities to use erlsom for SOAP. 
</div>
<div> </div>
<div>Regards,</div>
<div>Willem</div>
<div> </div>
<div>--------------------------</div>
<div>The schema:</div>
<div>
<p><xsd:schema xmlns:xsd='<a href="http://www.w3.org/2001/XMLSchema'">http://www.w3.org/2001/XMLSchema'</a>></p>
<p><xsd:element name='Export'><br>  <xsd:complexType><br>    <xsd:sequence><br>      <xsd:element name = 'Product' type='Product'/><br>    </xsd:sequence><br>  </xsd:complexType>
<br></xsd:element></p>
<p><xsd:complexType name='Product'><br>  <xsd:sequence><br>    <xsd:element name='SKU' type='xsd:string'/><br>    <xsd:element name='ItemName' type='xsd:string'/>
<br>    <xsd:element name='CollectionNo' type='xsd:integer'/><br>    <xsd:element name='Pages' type='xsd:integer'/><br>  </xsd:sequence><br></xsd:complexType></p>
<p></xsd:schema><br></p><br><br> </div>
<div><span class="gmail_quote">On 10/23/07, <b class="gmail_sendername">Hakan Mattsson</b> <<a href="mailto:hakan@erix.ericsson.se">hakan@erix.ericsson.se</a>> wrote:</span>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">On Tue, 23 Oct 2007, Joel Reymont wrote:<br><br>JR> Take a look at the following [1] and try to visualize an
<br>JR> implementation in Erlang. More thoughts after the example.<br>JR><br>JR> The data:<br>JR><br>JR> <Export><br>JR>    <Product><br>JR>      <SKU>403276</SKU><br>JR>      <ItemName>Trivet</ItemName>
<br>JR>      <CollectionNo>0</CollectionNo><br>JR>      <Pages>0</Pages><br>JR>    </Product><br>JR> </Export><br>JR><br>JR> The Ruby hPricot code:<br>JR><br>JR> FIELDS = %w[SKU ItemName CollectionNo Pages]
<br>JR><br>JR> doc = Hpricot.parse(File.read("my.xml"))<br>JR> (doc/:product).each do |xml_product|<br>JR>    product = Product.new<br>JR>    for field in FIELDS<br>JR>      product[field] = (xml_product/field.intern).first.innerHTML
<br>JR>    end<br>JR>    product.save<br>JR> end<br><br>At a first glance your Ruby code looks impressively<br>compact.  But the corresponding implementation in<br>Erlang is about the same size. What's the point in
<br>adding some syntactic sugar in order to make it even<br>more compact? It is just a matter of taste.<br><br>   % cat product.erl<br>   -module(product).<br>   -compile(export_all).<br>   -include_lib("xmerl/include/xmerl.hrl").
<br><br>    parse(File) -><br>       {#xmlElement{content = Exports}, _} = xmerl_scan:file(File),<br>       [{Tag, Val} || #xmlElement{content = Products} <- Exports,<br>                      #xmlElement{content = Fields} <- Products,
<br>                      #xmlText{parents = [{Tag, _} | _], value = Val}  <- Fields].<br><br>   % erl<br>   Erlang (BEAM) emulator version 5.5.5 [source] [async-threads:0] [kernel-poll:false]<br><br>   Eshell V5.5.5  (abort with ^G)
<br>   1> product:parse("my.xml").<br>   [{'SKU',"403276"},{'ItemName',"Trivet"},{'CollectionNo',"0"},{'Pages',"0"}]<br>   2><br><br>
/Håkan<br>_______________________________________________<br>erlang-questions mailing list<br><a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br><a href="http://www.erlang.org/mailman/listinfo/erlang-questions">
http://www.erlang.org/mailman/listinfo/erlang-questions</a><br></blockquote></div><br>