Precisei recentemente montar uma aplicação que fosse configurável, e que não fizesse acesso a nenhuma base de dados estruturada. A idéia era permitir que o usuário, um power user, fizesse as configurações, que eram poucas, sozinho. Como venho de olho no LINQ, e especificamente no LINQ to XML, não pensei duas vezes: vou configurar tudo em um XML simples e lê-lo com LINQ.

Segue o passo a passo. Foram pouquíssimas linhas de código e tempo de desenvolvimento. Você gasta mais tempo abobado com a capacidade da ferramenta do que com o desenvolvimento em si. Acaba sendo um bom exemplo de leitura de XML com LINQ.

  1. Crie um projeto, pode ser um console;
  2. Crie o XML com os dados que você vai precisar. Meu exemplo ficou assim:

        1 <?xml version="1.0" encoding="utf-8" ?>

        2 <configuracoes xmlns="algumacoisa">

        3   <app appId="1" logLigado="true" />

        4   <caminhosDePesquisa>

        5     <caminho enderecoFisico="C:\config" habilitado="true" />

        6     <caminho enderecoFisico="C:\Windows" habilitado="false" />

        7   </caminhosDePesquisa>

        8 </configuracoes>

  3. Crie o schema, clicando no menu XML > Create Schema. Salve o arquivo do schema no diretório da aplicação e o inclua no projeto.
  4. Inclua o atributo targetNamespace no Schema. O valor tanto faz, escolha um valor de namespace que você gosta, pode ser o nome do seu cachorro, da namorada, o que for. O schema vai ficar assim:

        1 <?xml version="1.0" encoding="utf-8"?>

        2 <xs:schema targetNamespace="algumacoisa" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">

        3   <xs:element name="configuracoes">

        4     <xs:complexType>

        5       <xs:sequence>

        6         <xs:element name="app">

        7           <xs:complexType>

        8             <xs:attribute name="appId" type="xs:unsignedByte" use="required" />

        9             <xs:attribute name="logLigado" type="xs:boolean" use="required" />

       10           </xs:complexType>

       11         </xs:element>

       12         <xs:element name="caminhosDePesquisa">

       13           <xs:complexType>

       14             <xs:sequence>

       15               <xs:element maxOccurs="unbounded" name="caminho">

       16                 <xs:complexType>

       17                   <xs:attribute name="enderecoFisico" type="xs:string" use="required" />

       18                   <xs:attribute name="habilitado" type="xs:boolean" use="required" />

       19                 </xs:complexType>

       20               </xs:element>

       21             </xs:sequence>

       22           </xs:complexType>

       23         </xs:element>

       24       </xs:sequence>

       25     </xs:complexType>

       26   </xs:element>

       27 </xs:schema>

  5. Altere seu XML para utilizar o namespace que você escolheu. A linha do elemento base fica assim (note que ao digitar xmlns e o igual, a opção do namespace que você digitou no targetnamespace do schema já fica disponível, escolha ela): 

        1 <?xml version="1.0" encoding="utf-8" ?>
       

  6. Vá até o arquivo Module1.vb, e importe o namespace do XML. Note que ao digitar "Imports" ele já te dá a opção de importar um namespace xml, e ao digitar o "=" após "xmlns", o namespace que você escolheu já aparece como opção. Fica assim:

        1 Imports <xmlns="algumacoisa">

  7. Na Sub Main abra o arquivo com a novíssimo classe XDocument, do namespace System.Xml.Linq lhe ajudando:

        4     Sub Main()

        5 

        6         Dim arquivo = IO.Path.Combine(IO.Directory.GetParent(My.Application.Info.DirectoryPath).Parent.FullName, "Configuracoes.xml")

        7         Dim XMLDoc = XDocument.Load(arquivo)

       17 

       18     End Sub

  8. Crie então o início do código Linq de consulta. Como você importou o namespace xml, quando digitar o primeiro ponto depois de XMLDoc você verá a possibilidade de utilizar as XML Axis properties. Veja na figura abaixo como o intelisense ajuda e em seguida o código:

    XMLAxisProperty 

        8         Dim consultaXML = From config In XMLDoc.<configuracoes>

  9. Faça a consulta dos atributos logLigado e Id (note o uso do "@" para obter o atributo):

        9         Dim appID As Integer = CInt(consultaXML.<app>.@appId)

       10         Dim blnLogLigado As Boolean = CBool(consultaXML.<app>.@logLigado)

       11         Console.WriteLine("O id da aplicação é ""{0}"" e o log está {1}.", appID.ToString(), If(blnLogLigado, "ligado", "desligado"))

  10. Consulte então os elementos de caminho de pesquisa:

       12         Console.WriteLine("Caminhos:")

       13         For Each caminho In consultaXML.<caminhosDePesquisa>.<caminho>

       14             Console.WriteLine("O endereço ""{0}"" está {1}.", caminho.@enderecoFisico, If(CBool(caminho.@habilitado), "habilitado", "desabilitado"))

       15         Next

 

Você deve ter percebido também nesse exemplo o uso do novo operador ternário If. Eu estou achando esse operador muito útil. Ele ajuda a deixar o código bem mais limpo. Usei também bastante inferência de tipo. Ah… como eu adoro digitar menos…

E como a comunidade de desenvolvimento adora se provocar, e o debate C# versus VB não termina nunca, vou aproveitar para contribuir: XML Axis properties são uma exclusividade do VB, não há nada nem de perto parecido no C#. Assim como XML Literals. Way cool!

Giovanni Bassi

Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.