我希望从我称为initialInspections.xml
的XML文件中加载重复的元素。问题是系统需要是动态的,并允许添加多个不同的inspectionNotes
。我需要输入所有这些,即使它们具有相同的名称。
如果有人能给我一个这样做的方法,我会非常感激,因为我现在已经搜索了近3个小时,但我找不到任何有效的方法。
我需要从每个inspectionNote
节点中获取所有数据,并将其放入名为initialInspectionNotes
的结构数组中。
以下是我现在所做的事情:
public int propertyID;
public string initialInspectorUsername;
public DateTime intialDateTime;
public struct initialInspectionNotes
{
public string locationWithinProperty;
public string locationExtraNote;
public string costCode;
public float estimatedTime;
}
private void finalInspection_Load(object sender, EventArgs e)
{
//Open the intialInspections xml file and load the values into the form
XmlDocument xdoc = new XmlDocument();
FileStream rFile = new FileStream(values.xmlInitialFileLocation, FileMode.Open);
xdoc.Load(rFile);
XmlNodeList list = xdoc.GetElementsByTagName("initialInspection");
for (int i = 0; i < list.Count; i++)
{
XmlElement initialInspection = (XmlElement)xdoc.GetElementsByTagName("initialInspection")[i];
XmlElement initialInspector = (XmlElement)xdoc.GetElementsByTagName("userInspection")[i];
XmlElement dateTime = (XmlElement)xdoc.GetElementsByTagName("dateTime")[i];
propertyID = int.Parse(initialInspection.GetAttribute("propertyID"));
initialInspectorUsername = initialInspector.InnerText;
intialDateTime = DateTime.Parse(dateTime.InnerText);
}
rFile.Close();
}
XML看起来像这样:
<?xml version="1.0" standalone="yes"?>
<initialInspections>
<initialInspection propertyID="1">
<userInspection>defaultadmin</userInspection>
<dateTime>07/11/2015 17:15:20</dateTime>
<inspectionNote>
<location>Dining Room</location>
<locationNote>Remove whole carpet, leave underlay</locationNote>
<CostCode>L1</CostCode>
<estimatedTime>5</estimatedTime>
</inspectionNote>
<inspectionNote>
<location>Other - See Notes</location>
<locationNote>On the marked area with orange spray paint.</locationNote>
<CostCode>B1</CostCode>
<estimatedTime>12</estimatedTime>
</inspectionNote>
</initialInspection>
</initialInspections>
非常感谢任何帮助。
答案 0 :(得分:3)
class Note
{
public string Location { get; set; }
public string LocationNote { get; set; }
public string CodeCost { get; set; }
public string EstimatedTime { get; set; }
}
var xml = XElement.Load(...your xml path here );
var data = xml.Descendants("initialInspection").Elements("inspectionNote").Select(n => new Note()
{
Location = n.Element("location").Value,
LocationNote = n.Element("locationNote").Value,
CodeCost = n.Element("CostCode").Value,
EstimatedTime = n.Element("estimatedTime").Value
}).ToList();
答案 1 :(得分:1)
一种可能性是使用LINQ2XML和LINQ Descendants方法一次性获取所有inspectionNotes
:
var xml = XDocument.Load(fileLocation); // for example c:\temp\input.xml
// fetch all inspectionNotes
var inspectionNotes = xml.Root.Descendants("inspectionNote").ToList();
// TODO: error handling!
// map inspectionNote node to custom structure
var arrayOfNotes = inspectionNotes.Select (n => new initialInspectionNotes
{
costCode = n.Element("CostCode").Value,
estimatedTime = float.Parse(n.Element("estimatedTime").Value),
locationExtraNote = n.Element("locationNote").Value,
locationWithinProperty = n.Element("location").Value,
})
// and convert the result to array holding elements of the custom structure
.ToArray();
foreach (var note in arrayOfNotes)
{
Console.WriteLine(note.locationExtraNote);
}
输出结果为:
Remove whole carpet, leave underlay
On the marked area with orange spray paint.
如果要读取和映射另一个XML节点(f.e。initialInspection
),则应用相同的逻辑。
如果您需要使用XmlReader
,请使用XPath,以便使用XmlNode.SelectSingleNode获取内部inspectionNote
元素和每个inspectionNote
元素的值和XmlNode.SelectNodes:
//Open the intialInspections xml file and load the values into the form
XmlDocument xdoc = new XmlDocument();
FileStream rFile = new FileStream(values.xmlInitialFileLocation, FileMode.Open);
xdoc.Load(rFile);
XmlNodeList list = xdoc.GetElementsByTagName("initialInspection");
// create list of initialInspectionNotes in order to add as many nodes as needed
var notes = new List<initialInspectionNotes>();
// map data
for (int i = 0; i < list.Count; i++)
{
// read data
XmlElement initialInspection = (XmlElement)xdoc.GetElementsByTagName("initialInspection")[i];
XmlElement initialInspector = (XmlElement)xdoc.GetElementsByTagName("userInspection")[i];
XmlElement dateTime = (XmlElement)xdoc.GetElementsByTagName("dateTime")[i];
propertyID = int.Parse(initialInspection.GetAttribute("propertyID"));
initialInspectorUsername = initialInspector.InnerText;
intialDateTime = DateTime.Parse(dateTime.InnerText);
// fetch notes!
var inspectionNotes = initialInspection.SelectNodes("inspectionNote");
foreach (XmlNode inspectionNote in inspectionNotes)
{
// insert data into list
notes.Add(new initialInspectionNotes
{
locationExtraNote = inspectionNote.SelectSingleNode("locationNote").InnerText,
costCode = inspectionNote.SelectSingleNode("CostCode").InnerText,
locationWithinProperty = inspectionNote.SelectSingleNode("location").InnerText
});
}
}
// convert to array if needed
//var arrayOfNotes = notes.ToArray();
rFile.Close();
无论XML包含多少inspectionNote
个元素,列表都是如此。数组将全部读取。
答案 2 :(得分:0)
class InitialInspectionNotes
{
public string Location { get; set; }
public string LocationNote { get; set; }
public string CodeCost { get; set; }
public string EstimatedTime { get; set; }
}
var xdoc = XDocument.Load("yourpath\filename.xml");
var dataXml = xdoc.Descendants("initialInspection").Elements("inspectionNote").Select(n => new InitialInspectionNotes()
{
Location = n.Element("location").Value,
LocationNote = n.Element("locationNote").Value,
CodeCost = n.Element("CostCode").Value,
EstimatedTime = n.Element("estimatedTime").Value
}).ToList();
var xmlList = new List<object>();
for (int i = 0; i < dataXml.Count; i++)
{
xmlList.Add(dataXml[i]);
}
答案 3 :(得分:0)
尽管上面的所有答案可能都有效,但我发现仅读取元素非常复杂。我找到了一个更简单的解决方案,我想在这种情况下与未来的观众分享。
假设您已将文档流读入名为 XmlDocument
的 document
对象。
var dataNodes = document.GetElementsByTagName("Data");
var toList = dataNodes.OfType<XmlElement>().ToList();
就我而言,Data
节点没有被重复调用。因此这是有效的,现在我能够附加多个具有相同名称的节点。