<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Escalare - A louca jornada de um programador &#187; xml</title>
	<atom:link href="http://gbenatti.net/blog/category/xml/feed/" rel="self" type="application/rss+xml" />
	<link>http://gbenatti.net/blog</link>
	<description>Um blog com a jornada deste que lhes fala no mundo da programação de dispositivos móveis, jogos e linguagens de programação.</description>
	<lastBuildDate>Mon, 19 Apr 2010 15:00:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Truques em Scala &#8211; Como fazer parsing de um xml</title>
		<link>http://gbenatti.net/blog/2009/10/truques-em-scala-como-fazer-parsing-de-um-xml/</link>
		<comments>http://gbenatti.net/blog/2009/10/truques-em-scala-como-fazer-parsing-de-um-xml/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 16:35:00 +0000</pubDate>
		<dc:creator>gbenatti</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[truques]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://escalare.wordpress.com/2009/10/27/truques-em-scala-como-fazer-parsing-de-um-xml</guid>
		<description><![CDATA[Ontem eu precisei extrair alguns dados de um xml, e acho que as lições aprendidas merecem ficar registradas, vai que mais alguem nesse mundão precisa fazer algo assim.



&#60;request service=&#34;Service 1&#34;&#62;


&#160; &#60;extra&#62;


&#160; &#160; &#60;entry key=&#34;key1&#34;&#62;value1&#60;/entry&#62;


&#160; &#160; &#60;entry key=&#34;key2&#34;&#62;value2&#60;/entry&#62;


&#160; &#60;/extra&#62;


&#60;/request&#62;



O objetivo era extrair o nome do service como uma string e as entries como um map de [...]]]></description>
			<content:encoded><![CDATA[<p>Ontem eu precisei extrair alguns dados de um xml, e acho que as lições aprendidas merecem ficar registradas, vai que mais alguem nesse mundão precisa fazer algo assim.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;request</span> <span class="re0">service</span>=<span class="st0">&quot;Service 1&quot;</span><span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;extra<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;entry</span> <span class="re0">key</span>=<span class="st0">&quot;key1&quot;</span><span class="re2">&gt;</span></span>value1<span class="sc3"><span class="re1">&lt;/entry<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;entry</span> <span class="re0">key</span>=<span class="st0">&quot;key2&quot;</span><span class="re2">&gt;</span></span>value2<span class="sc3"><span class="re1">&lt;/entry<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="sc3"><span class="re1">&lt;/extra<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/request<span class="re2">&gt;</span></span></span></div>
</li>
</ol>
</div>
<p>O objetivo era extrair o nome do service como uma string e as entries como um map de key values.</p>
<p>O servico como string é bem facil, considerando que o xml esta em uma variavel serviceXml, teriamos:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">val serviceName = <span class="br0">&#40;</span>serviceXml\<span class="st0">&quot;@service&quot;</span><span class="br0">&#41;</span>.<span class="me1">text</span></div>
</li>
</ol>
</div>
<p>O que isso faz é basicamente pegar o attributo service do nó em questão e com esse dado pegar o nó como text.</p>
<p>A segunda parte é um pouco mais complexa então vamos por parte, primeiro pegamos as entries:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">val entries = serviceXml\<span class="st0">&quot;extra&quot;</span>\\<span class="st0">&quot;entry&quot;</span></div>
</li>
</ol>
</div>
<p>Esse codigo executa basicamente um XPath extraindo do xml o nó &#8220;extra&#8221; e deste a lista de nós &#8220;entry&#8221;</p>
<p>Então, para cada entry extraimos uma tupla com o valor da key e o value:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">val entriesTuple = <span class="kw1">for</span> <span class="br0">&#40;</span>entry &lt;- entries<span class="br0">&#41;</span> <span class="kw1">yield</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>entry\<span class="st0">&quot;@key&quot;</span><span class="br0">&#41;</span>.<span class="me1">text</span>, entry.<span class="me1">text</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Aqui usamos um for expression para percorrer a lista entries e retornar (usando yield) uma tupla que contem o valor da key e o inner text da entry</p>
<p>E por fim criar um Map com esses dados:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">val mapResult = Map<span class="br0">&#40;</span>entriesTuple: _*<span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Por fim, como construir um Map apartir de uma lista, ou nesse caso de um generator ?</p>
<p>Maps podem ser contruidos usando de um numero variavel de tuplas usando algo como Map(tupla1, tupla2, tuplaN).</p>
<p>Se tentarmos usar Map(entriesTuple) o compilador vai reclamar falando que esse metodo nao pode ser executado com uma Seq[(String, String)], ou seja, uma sequencia de tuplas contendo duas Strings.</p>
<p>Temos que dar um jeito de passar essa Seq como um numero variavel de argumentos, e os desenvolvedores de Scala nos deram uma forma de fazer isso, quando temos que passar uma lista para um método que espera um número variavel de argumentos podemos fazer assim:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">Map<span class="br0">&#40;</span>entriesTuples: _*<span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Essa anotação diz ao compilador para expandir os parametros</p>
<p>Juntando tudo temos:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">val mapResult = Map<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw1">for</span> <span class="br0">&#40;</span>entry &lt;- serviceXml\<span class="st0">&quot;extra&quot;</span>\\<span class="st0">&quot;entry&quot;</span><span class="br0">&#41;</span> <span class="kw1">yield</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>entry\<span class="st0">&quot;@key&quot;</span><span class="br0">&#41;</span>.<span class="me1">text</span>, entry.<span class="me1">text</span><span class="br0">&#41;</span><span class="br0">&#41;</span>: _*<span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Muita explicação pra pouco código, assim é Scala</p>
<p>Cheers</p>
]]></content:encoded>
			<wfw:commentRss>http://gbenatti.net/blog/2009/10/truques-em-scala-como-fazer-parsing-de-um-xml/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

