我有以下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中的第三行检索值,并继续跳到它应该解析的那一行之后的下一行。
我该如何解决这个问题?
答案 0 :(得分: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阅读有一个非常明确的想法。此外,为了以防万一,还可以包含一个尝试...捕捉。请注意,读取/处理变量时的任何错误都会导致读取过程立即停止。
答案 1 :(得分: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);
}
希望这会有所帮助......