none
Usando XML no C# RRS feed

  • Pergunta

  • Olá!


    A pouco estive desenvolvendo um projeto e surgiu uma necessidade. Edição de um arquivo XML.


    O formato do arquivo era mais ou menos assim:

    <?xml version="1.0" standalone="yes"?>
    <Estatico>
      <ParametrosFixos>
        <parametro tag="parametro1" valor="valor1" T="T1" V="V1" />
        <parametro tag="parametro2" valor="valor2" T="T2" V="V2" />
        <parametro tag="parametro3" valor="valor3" T="T3" V="V3" />
      </ParametrosFixos>
      <ParametrosAjustaveis>
        <ajustavel tag="Tarja1">
          <linha num="1">
            <conf tag="T10" valor="V10" />
            <conf tag="T20" valor="V20" />
            <conf tag="T30" valor="V30" />
            <conf tag="T40" valor="V40" />
          </linha>
          <linha num="2">
            <conf tag="T22" valor="V22" />
            <conf tag="T33" valor="V33" />
            <conf tag="T44" valor="V44" />
            <conf tag="T55" valor="V55" />
          </linha>
        </ajustavel>
        <ajustavel tag="Tarja2">
          <linha num="1">
            <conf tag="T52" valor="V52" />
          </linha>
          <linha num="2">
            <conf tag="T63" valor="V63" />
          </linha>
        </ajustavel>
      </ParametrosAjustaveis>
    </Estatico>
    


    Esse arquivo é carregado em um DataSet para fazer alterações em uma grid:


                        string file = @"c:\teste.xml";
                        using (FileStream stream = File.OpenRead(file))
                        {
                            DataSet dt = new DataSet();
                            if (File.Exists(file))
                           {
                                dt.ReadXml(URLFile);
                           }
                        }
    O problema acontece quando tento incluir algum valor no node <ParametrosFixos>.


                    dt.WriteXml(file);
    



    Em vez do insert ser feito dentro do node, o insert é feito na raiz do arquivo:

    <?xml version="1.0" standalone="yes"?>
    <Estatico>
      <ParametrosFixos>
        <parametro tag="parametro1" valor="valor1" T="T1" V="V1" />
        <parametro tag="parametro2" valor="valor2" T="T2" V="V2" />
        <parametro tag="parametro3" valor="valor3" T="T3" V="V3" />
      </ParametrosFixos>
      <parametro tag="parametro4" valor="valor4" T="T4" V="V4" />
      <parametro tag="parametro5" valor="valor5" T="T5" V="V5" />
      <ParametrosAjustaveis>
        <ajustavel tag="Tarja1">
          <linha num="1">
            <conf tag="T10" valor="V10" />
            <conf tag="T20" valor="V20" />
            <conf tag="T30" valor="V30" />
            <conf tag="T40" valor="V40" />
          </linha>
          <linha num="2">
            <conf tag="T22" valor="V22" />
            <conf tag="T33" valor="V33" />
            <conf tag="T44" valor="V44" />
            <conf tag="T55" valor="V55" />
          </linha>
        </ajustavel>
        <ajustavel tag="Tarja2">
          <linha num="1">
            <conf tag="T52" valor="V52" />
          </linha>
          <linha num="2">
            <conf tag="T63" valor="V63" />
          </linha>
        </ajustavel>
      </ParametrosAjustaveis>
    </Estatico>


    Alguém aqui já teve alguma experiência parecida? Será que poderiam me dar um luz?

    segunda-feira, 27 de julho de 2009 21:11

Respostas

  • Samucasam,

    Quando você faz a leitura por meio do ReadXml e o seu XML não possui um schema definido, esse é deduzido. No seu caso existirá uma tabela para cada elemento sendo que os atributos desses elementos se transformarão em colunas dessas tabelas.

    Uma possível solução seria utilizar a classe XMLDocument e criar esses novos elementos.

    Ex:

    // cria xml document
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(@"c:\temp\original.xml");

    // cria navigator para mover a posição para o elemento "ParametrosFixos" (utilizando XPath)
    XPathNavigator xpathNav = xmlDoc.CreateNavigator();
    XPathNavigator node = xpathNav.SelectSingleNode(@"//ParametrosFixos");

    // adiciona o parâmetro
    node.AppendChildElement(node.Prefix, "parametro", node.NamespaceURI, "");

    // move posição para o parâmetro criado
    node.MoveToFirstChild();
    do {
    } while (node.MoveToNext());

    // adiciona atributos ao parâmetro criado
    node.CreateAttribute(node.Prefix, "tag", node.NamespaceURI, "parametro4");
    node.CreateAttribute(node.Prefix, "valor", node.NamespaceURI, "valor4");
    node.CreateAttribute(node.Prefix, "T", node.NamespaceURI, "T4");
    node.CreateAttribute(node.Prefix, "V", node.NamespaceURI, "V4");

    // salva xml
    xmlDoc.Save(@"c:\temp\novo.xml");


    Espero ter ajudado.

    Att.

    Ari C. Raimundo
    terça-feira, 28 de julho de 2009 02:42

Todas as Respostas

  • Samucasam,

    Quando você faz a leitura por meio do ReadXml e o seu XML não possui um schema definido, esse é deduzido. No seu caso existirá uma tabela para cada elemento sendo que os atributos desses elementos se transformarão em colunas dessas tabelas.

    Uma possível solução seria utilizar a classe XMLDocument e criar esses novos elementos.

    Ex:

    // cria xml document
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(@"c:\temp\original.xml");

    // cria navigator para mover a posição para o elemento "ParametrosFixos" (utilizando XPath)
    XPathNavigator xpathNav = xmlDoc.CreateNavigator();
    XPathNavigator node = xpathNav.SelectSingleNode(@"//ParametrosFixos");

    // adiciona o parâmetro
    node.AppendChildElement(node.Prefix, "parametro", node.NamespaceURI, "");

    // move posição para o parâmetro criado
    node.MoveToFirstChild();
    do {
    } while (node.MoveToNext());

    // adiciona atributos ao parâmetro criado
    node.CreateAttribute(node.Prefix, "tag", node.NamespaceURI, "parametro4");
    node.CreateAttribute(node.Prefix, "valor", node.NamespaceURI, "valor4");
    node.CreateAttribute(node.Prefix, "T", node.NamespaceURI, "T4");
    node.CreateAttribute(node.Prefix, "V", node.NamespaceURI, "V4");

    // salva xml
    xmlDoc.Save(@"c:\temp\novo.xml");


    Espero ter ajudado.

    Att.

    Ari C. Raimundo
    terça-feira, 28 de julho de 2009 02:42

  • Muio obrigado Ari.

    A solução proposta por você atende bem a necessidade.

    Perfeito.

    terça-feira, 28 de julho de 2009 17:31