从XML文件加载重复的元素

时间:2015-11-24 18:34:18

标签: c# xml

我希望从我称为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>

非常感谢任何帮助。

4 个答案:

答案 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)

一种可能性是使用LINQ2XMLLINQ 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)

尽管上面的所有答案可能都有效,但我发现仅读取元素非常复杂。我找到了一个更简单的解决方案,我想在这种情况下与未来的观众分享。

假设您已将文档流读入名为 XmlDocumentdocument 对象。

var dataNodes = document.GetElementsByTagName("Data");

var toList = dataNodes.OfType<XmlElement>().ToList();

就我而言,Data 节点没有被重复调用。因此这是有效的,现在我能够附加多个具有相同名称的节点。