Xmltextreader.Getattribute returns the null value

Asked

Viewed 107 times

1

I made a base code in XML and I would like to import the attributes and values according to the code:

<?xml version="1.0" encoding="UTF-8" ?>
<!-- MAIN SCRIPT FILE FOR JAVA 7u80 MINECRAFT SERVER -->
<params count="3">
    <param name="commandLine" value="java.exe -jar @commandForge@ nogui" SerializeAs="[mscorlib]::System.Process" />
    <param name="commandForge" value="forge-1.7.10-10.13.4.1448-1.7.10-universal.jar" SerializeAs="[mscorlib]::System.String" />
    <param name="previewOutput" value="True" SerializeAs="Boolean" />
</params>

And I ran the following code to get the attribute count of the first element:

internal void LoadXML()
        {
            try
            {
                if (s != null)
                {
                    KeysAndValues = new Dictionary<object, object>();
                    XmlTextReader xmlreader = new XmlTextReader(s);

                    xmlreader.ReadStartElement("params");
                    int count = int.Parse(xmlreader.GetAttribute("count")); 
         // acontece o erro aqui na linha acima!

                    for (int i = 0; i < count; i++)
                    {
                        var name= "";
                        var value = "";

                        xmlreader.ReadStartElement("param");
                        name = xmlreader.GetAttribute(0);
                        value = xmlreader.GetAttribute(1);
                        xmlreader.ReadEndElement();

                        KeysAndValues.Add(name, value);

                    }


                    xmlreader.ReadEndElement();
                }
            }
            catch (Exception e)
            {
                ExceptionForm exceptionA = new ExceptionForm(e);
                exceptionA.ShowDialog();
            }
        }

Soon after that I compile and run the application and the following appears:

System.ArgumentNullException: Valor não pode ser nulo.
Nome do parâmetro: String
   em System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   em System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   em Start.XMLScriptParser.LoadXML() na C:\Users\Nathan\Documents\Visual Studio 2008\Projects\Start\Start\XMLScriptParser.cs:linha 37

Since I’ve provided all the data he asked for!

Complete code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;

namespace Start
{
    public class XMLScriptParser
    {
        Dictionary<object, object> KeysAndValues;
        Stream s;

        public XMLScriptParser(Stream s)
        {
            this.s = s;
        }

        public object GetValueFrom(object Key)
        {
            return KeysAndValues[Key];
        }

        public void TryParse() { LoadXML(); }

        internal void LoadXML()
        {
            try
            {
                if (s != null)
                {
                    KeysAndValues = new Dictionary<object, object>();
                    XmlTextReader xmlreader = new XmlTextReader(s);

                    xmlreader.ReadStartElement("params");
                    int count = int.Parse(xmlreader.GetAttribute("count"));

                    for (int i = 0; i < count; i++)
                    {
                        var name= "";
                        var value = "";

                        xmlreader.ReadStartElement("param");
                        name = xmlreader.GetAttribute(0);
                        value = xmlreader.GetAttribute(1);
                        xmlreader.ReadEndElement();

                        KeysAndValues.Add(name, value);

                    }


                    xmlreader.ReadEndElement();
                }
            }
            catch (Exception e)
            {
                ExceptionForm exceptionA = new ExceptionForm(e);
                exceptionA.ShowDialog();
            }
        }
    }
}

The same I want to do with this XML document:

<?xml version="1.0" encoding="UTF-8" ?>
<params count="12">
    <param name="Locale" value="PT-BR" SerializeAs="[mscorlib]::String" />
    <param name="DisplayName" value="Nathan Ferreira" SerializeAs="[mscorlib]::String" />
    <param name="MainText" value="Start :: [Empty.xml]" SerializeAs="[mscorlib]::String" />
    <param name="ExceptionText" value="Ops! Tem algo errado" SerializeAs="[mscorlib]::String" />

    <param name="MainForm.Label1" value="Arquivo de script:" SerializeAs="[mscorlib]::String" />
    <param name="MainForm.Label2" value="Enviar Comando" SerializeAs="[mscorlib]::String" />
    <param name="MainForm.Label3" value="Uso de Mem. RAM" SerializeAs="[mscorlib]::String" />

    <param name="MainForm.Button1" value="Carregar e Iniciar" SerializeAs="[mscorlib]::String" />
    <param name="MainForm.Button2" value=">>" SerializeAs="[mscorlib]::String" />

    <param name="MainForm.Page1" value="Linha de comando" SerializeAs="[mscorlib]::String" />
    <param name="MainForm.Page2" value="Configuração do Script" SerializeAs="[mscorlib]::String" />

    <param name="MainForm.ProgressBarValue" value="0" SerializeAs="[mscorlib]::Int32" />

</params>
  • 1

    xmlreader.GetAttribute("count") is returning null. I usually open XML using Linq, so I don’t know what might be wrong, but I’ll try it here and see what the problem is.

  • How would it be using Linq? I want to make it as if it were a list with param name and param value all in one SortedDictionary or a Dictionary normal.

  • I’ll take an example.

  • okay wait! . .

  • You managed to solve?

  • I haven’t had time to edit the code yet but rest assured I’ll do this tomorrow.

Show 1 more comment

1 answer

2


The problem is that the return of xmlreader.GetAttribute("count") is being null and, as the error itself says, the value passed to int.Parse() cannot be null.

The mistake I don’t really know where it is, maybe you need to pick up the attribute in a different way, I don’t know.

I made an example code (using Linq) based on the general purpose of the routine (which you explained in the comments)

I want to make it like a list with param name and param value all in one SortedDictionary or a Dictionary normal.

The code below returns a Dictionary with the Key being the value of the attribute name and the value being the value of the attribute value.

var doc = XDocument.Load("arq.xml");    
var count = doc.Descendants("params").FirstOrDefault()?.Attribute("count").Value;

var query = doc.Descendants("param")
                    .Select(x => new
                    {
                        Name = x.Attribute("name").Value,
                        Value = x.Attribute("value").Value
                    }).ToDictionary(o => o.Name, o => o.Value);

Notice that I have not seen if the nodes or attributes really exist.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.