4

我有以下 XML 片段-

-<Row>
 <RowType Id="1"Label="Scotland">1985</RowType>
 <Year Id="11"Label="1994"/>
 <Value Id="123">18</Value>
 <Field Id="123"Label="Country">16</Field>
 <Field Id="123"Label="Soccer">Yes</Field>
</Row>
-<Row>
 <RowType Id="1"Label="England">1986</RowType>
 <Year Id="11"Label="1994"/>
 <Value Id="123">19</Value>
 <Field Id="123"Label="Country">16</Field>
 <Field Id="123"Label="Soccer">Yes</Field>
</Row>
-<Row>
 <RowType Id="1"Label="Wales">1987</RowType>
 <Year Id="11"Label="1994"/>
 <Value Id="123">20</Value>
 <Field Id="123"Label="Country">16</Field>
 <Field Id="123"Label="Soccer">Yes</Field>
</Row>

XmlReader用来从中检索特定数据,就像这样-

using (XmlReader reader = XmlReader.Create(new StringReader(xml)))
        {
            string country = "";
            string Year = "";
            string count = "";
            string tss= "";
            string tss2 = "";


            reader.MoveToContent();
            while (reader.Read())
            {

                reader.ReadToFollowing("RowType");
                country = reader.GetAttribute("Label");
                country = country.Replace("'", "");

                reader.ReadToFollowing("Year");
                Year = reader.GetAttribute("Label");

                reader.ReadToFollowing("Value");
                count = reader.ReadElementContentAsString();

                reader.ReadToFollowing("Field");
                tss = reader.GetAttribute("Label");

                reader.ReadToFollowing("Field");
                tss2 = reader.GetAttribute("Label");
            }
        }

这在第一次迭代中运行良好,但是在第二次迭代中,它从 XML 中的第三行检索值,并在它应该解析的行之后继续跳到下一行。

我该如何解决这个问题?

4

2 回答 2

5

实际上,您的代码是正确的;不正确的是文件的结构。或者更好的是,您的代码不考虑文档的特定结构。

您可以通过添加以下位来更改它:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create(new StringReader(xml), settings))

默认情况下,XMLReader 需要ConformanceLevel.Document,因此该文件应具有如下结构:

<main>
<Row id="5">
 <RowType Id="1" Label="Scotland">1985</RowType>
 <Year Id="11" Label="1994"/>
 <Value Id="123">18</Value>
 <Field Id="123" Label="Country">16</Field>
 <Field Id="123" Label="Soccer">Yes</Field>
</Row>
<Row id="1">
 <RowType Id="1" Label="England">1986</RowType>
 <Year Id="11" Label="1994"/>
 <Value Id="123">19</Value>
 <Field Id="123" Label="Country">16</Field>
 <Field Id="123" Label="Soccer">Yes</Field>
</Row>
<Row id="4">
 <RowType Id="1" Label="Wales">1987</RowType>
 <Year Id="11" Label="1994"/>
 <Value Id="123">20</Value>
 <Field Id="123" Label="Country">16</Field>
 <Field Id="123" Label="Soccer">Yes</Field>
</Row>
</main>

我知道元素之间缺乏分隔(例如,Id="1"Label="Scotland"而不是Id="1" Label="Scotland")是一个错字,因为在任何情况下都必须存在分隔。

- - - - - - - - - - 更新

您报告说即使更改了一致性级别,您的代码也没有提供预期的结果。我对您的代码进行了新的测试,它运行良好;至少,它可以正确迭代。因此,我的理解是您想要检索与您的代码不同的值(它混合了应用程序名称、属性和内容)。

下面你可以看到我自己的代码(尽管我坚持你的也可以遍历给定的信息),这比你的更具适应性;我还在我认为您想要检索与您的代码不同的信息的部分中添加了一些注释。基本思想只是从内容(内容)中检索信息,但您的代码可以从任何地方获取信息。

        string path = @"XML file";
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.ConformanceLevel = ConformanceLevel.Fragment;
        using (XmlReader reader = XmlReader.Create(path, settings))
        {
            string country = "";
            string Year = "";
            string count = "";
            string tss = "";
            string tss2 = "";

            while (reader.ReadToFollowing("Row"))
            {
                XmlReader reader2 = reader.ReadSubtree();
                while (reader2.Read())
                {
                    if (reader2.NodeType == XmlNodeType.Element)
                    {
                        if (reader2.Name == "RowType")
                        {
                            country = reader2.GetAttribute("Label");
                            country = country.Replace("'", ""); //country_year = reader.ReadElementContentAsString(); -> "Scotland" -> 1985
                        }
                        else if (reader2.Name == "Year")
                        {
                            //IF XML IS -> <Year Id="11">1994<Year/>
                            //Then -> Year = reader2.GetAttribute("Label")
                            Year = reader2.GetAttribute("Label"); //-> 1994
                        }
                        else if (reader2.Name == "Value")
                        {
                            count = reader2.ReadElementContentAsString(); 
                        }
                        else if (reader2.Name == "Field")
                        {
                            if (reader2.GetAttribute("Label") == "Country")
                            {
                                tss = reader2.ReadElementContentAsString(); //I understand that this is what you want to read, instead the Label name
                            }
                            else if (reader2.GetAttribute("Label") == "Soccer")
                            {
                                tss2 = reader2.ReadElementContentAsString();//I understand that this is what you want to read, instead the Label name
                            }
                        }
                    }
                }
            }
        }

这应该提供您正在寻找的东西;或者,在最坏的情况下,对如何处理 XML 读取有一个非常清晰的想法。此外,包含一个 try...catch 可能是一件好事,以防万一;请注意,读取/处理变量时的任何错误都会导致读取过程立即停止。

于 2013-07-03T16:32:15.747 回答
0

如果您愿意,我们可以使用 LINQ 来完成这项工作。

如果您真的想将 Xml 中的所有值读取到某个变量中...您可以尝试类似的行...

        XElement po = XElement.Load(@"SoccerCup.xml");
        IEnumerable<XElement> childElements =
            from el in po.Elements()
            select el;
        foreach (XElement el in childElements)
        {
            var Year=el.Element("Year").Value;
            var country  = el.Element("country").Value;
            var count =el.Elemet("Value").Value;
            Console.WriteLine("Year: " + Year);
            Console.WriteLine("Country: " + country);
            Console.WriteLine("Count: " + count);
        }

希望这可以帮助...

于 2013-07-03T16:16:36.540 回答