到达XML字符串末尾时的对象引用问题

时间:2009-08-25 19:28:08

标签: c# xml parsing

我一直在为这个数据结构的特定文件开发一个小的xml解析器:

<questionnaire type="Echo">
    <quest etat="0" ord="0">
        <intro>
            <t>bla bla bla</t>
        </intro>
        <rep1>
            <t>word</t>
            <ev id="Q0R1"/>
        </rep1>
        <rep2>
            <t>word</t>
            <ev id="Q0R2"/>
        </rep2>
    </quest>
</questionnaire>

<quest></quest>标签实际上重复了70次。

这是我在C#中开发的解析器,它接受包含XML的参数“xmlString”来解析:

XmlTextReader reader = new XmlTextReader(new System.IO.StringReader(xmlString));

while(reader.ReadToFollowing("quest"))
{
    Console.WriteLine("=================================");

    Console.WriteLine("ID : " + reader.GetAttribute("ord").ToString());

    reader.ReadToFollowing("intro");
    reader.ReadToFollowing("t");
    Console.WriteLine("TEXTE : " + reader.ReadString());

    reader.ReadToFollowing("rep1");
    reader.ReadToFollowing("t");
    Console.WriteLine("REPONSE1 : " + reader.ReadString());
    reader.ReadToFollowing("ev");
    Console.WriteLine("CLE1 : " + reader.GetAttribute("id").ToString());

    reader.ReadToFollowing("rep2");
    reader.ReadToFollowing("t");
    Console.WriteLine("REPONSE2 : " + reader.ReadString());
    reader.ReadToFollowing("ev");
    Console.WriteLine("CLE2 : " + reader.GetAttribute("id").ToString());

    Console.WriteLine("ETAT : False");
}

通过69第一个&lt; quest&gt;,但是当到达第70个时,字段TEXTE和REPONSE1为空并且在该行处经历NullReferenceException:

Console.WriteLine("CLE1 : " + reader.GetAttribute("id").ToString());

谁能告诉我有什么问题? 提前谢谢。

2 个答案:

答案 0 :(得分:0)

GetAttribute 如果当前节点的属性不存在,则返回null。因此,对null对象执行ToString()会抛出 NullReferenceException

要修复它,请在执行ToString()之前检查空值。

顺便说一句, GetAttribute 已经返回一个字符串,因此调用ToString几乎没用。

答案 1 :(得分:0)

为什么不使用XPath?

XPathDocument doc = new XPathDocument("sample.xml");
var navigator = doc.CreateNavigator();
var iterator = navigator.Select("/questionnaire/quest");
while (iterator.MoveNext())
{
    Console.WriteLine("=================================");

    Console.WriteLine("ID : " + iterator.Current.GetAttribute("ord", String.Empty));
    var intro = iterator.Current.Select("intro/t");
    if (intro.MoveNext())
    {
        Console.WriteLine("TEXTE : " + intro.Current.Value);
    }

    var response1 = iterator.Current.Select("rep1/t");
    if (response1.MoveNext())
    {
        Console.WriteLine("REPONSE1 : " + response1.Current.Value);
    }

    var cle1 = iterator.Current.Select("rep1/ev/@id");
    if (cle1.MoveNext())
    {
        Console.WriteLine("CLE1 : " + cle1.Current.Value);
    }

    var response2 = iterator.Current.Select("rep2/t");
    if (response2.MoveNext())
    {
        Console.WriteLine("REPONSE2 : " + response2.Current.Value);
    }

    var cle2 = iterator.Current.Select("rep2/ev/@id");
    if (cle2.MoveNext())
    {
        Console.WriteLine("CLE2 : " + cle2.Current.Value);
    }

    Console.WriteLine("ETAT : False");
}