简体   繁体   English

读取XML节点

[英]Reading XML Nodes

I have the following XML file. 我有以下XML文件。 I am trying to read the startDate node of the dept element but don't want to read the "startDate" node of any of the rest of the child elements like "DeptRoles". 我正在尝试读取dept元素的startDate节点,但不想读取其余所有子元素(如“ DeptRoles”)的“ startDate”节点。

<dept operationalStatus="active" primaryRole="Admin" depChangeDate="20130420">      
    <startDate type="legal">20130401</startDate>
    <endDate type="legal"></endDate>
    <startDate type="operational">20130320</startDate>
    <endDate type="operational"></endDate>  
    <DeptRoles>         
        <DeptRole name="Other dept" status="active">
            <startDate type="legal">20130401</startDate>
            <endDate type="legal"></endDate>
            <startDate type="operational">20130320</startDate>
            <endDate type="operational"/>
            <isPrimary/>                
        </DeptRole>
    </DeptRoles>
</dept>

This is my c# code. 这是我的C#代码。 This code is also getting the DeptRole startDate element, which I dont want. 这段代码也得到了DeptRole startDate元素,我不想。

public static List<organisation> Getorgdata(string data)
    {
        List<organisation> listorgdata = new List<organisation>();
        XmlReader xmlReader = XmlReader.Create(new StringReader(data));
        while (xmlReader.Read())
        {
            if (xmlReader.NodeType == XmlNodeType.Element)
            {
                organisation record = new organisation();
                if (xmlReader.HasAttributes && xmlReader.Name == "dept")
                {
                    record.orgOperationalStatus = xmlReader.GetAttribute("operationalStatus");
                    record.orgLegalStatus = xmlReader.GetAttribute("legalStatus");
                }
                else if (xmlReader.Name == "name")
                {
                    record.orgName = xmlReader.ReadElementString("name");
                }

                else if (xmlReader.Name == "startDate" || xmlReader.Name == "endDate")
                {
                    if (xmlReader.GetAttribute("type") == "legal")
                    {
                        record.orgLegalStartDate = xmlReader.ReadElementString("startDate");
                        record.orgLegalEndDate = xmlReader.ReadElementString("endDate");
                    }
                    else if (xmlReader.GetAttribute("type") == "operational")
                    {
                        record.orgOperationalStartDate = xmlReader.ReadElementString("startDate");
                        record.orgOperationalEndDate = xmlReader.ReadElementString("endDate");
                        listorgdata.Add(record);
                    }
                }
            }
        }
        return listorgdata;
    }

I would use LINQ to XML (as others have suggested). 我将使用LINQ to XML(正如其他人所建议的)。 Below is sample code that somewhat matches your posted code - explanation of the code follows. 以下是与您发布的代码有些匹配的示例代码-代码说明如下。

public static List<organisation> Getorgdata(string data)
{

    List<organisation> listorgdata = new List<organisation>();
    XDocument xDoc = XDocument.Parse(data);

    listorgdata = xDoc.Root.Elements("dept")
                  .Select(x => new organisation()
                  {
                      orgOperationalStatus = (string)x.Attribute("operationalStatus"),
                      orgLegalStartDate = (string)x.Elements("startDate")
                                          .Where(x1 => (string)x1.Attribute("type") == "legal")
                                          .First(),
                      orgOperationalStartDate = (string)x.Elements("startDate")
                                                .Where(x1 => (string)x1.Attribute("type") == "operational")
                                                 .First()
                  }).ToList();

     return listorgdata;
}    

The first thing the above code does is load the XML into an XDocument with the XDocument.Parse method. 上面的代码要做的第一件事是使用XDocument.Parse方法将XML加载到XDocument.Parse

The query then parses the XML document and returns a list of populated organization objects. 然后,查询将解析XML文档并返回已填充的organization对象的列表。 It goes something like this. 它像这样。

  1. Get all the <dept> elements (and the child elements). 获取所有<dept>元素(和子元素)。
  2. With each <dept> element, create a new instance of organisation and assign the value of the "operationalStatus" attribute to the operationalStatus property of organisation . 与每个<dept>元素,创建的新实例organisation和分配“OperationalStatus的”属性到的值operationalStatus财产organisation The (string) cast will gracefully handle the situation where the specified attribute is not present. (string)强制转换将很好地处理指定属性不存在的情况。
  3. For the legal start date, we do a query on the <startDate> children of the <dept> element, taking the first one that has an attribute "type" equal to "legal". 对于合法的开始日期,我们对<dept>元素的<startDate>子元素进行查询,并获取第一个属性为“ type”等于“ legal”的元素。
  4. For the operational start date, we do a similar query to number 3, except it's looking for "operational". 对于运营开始日期,我们与数字3进行类似的查询,只是它要查找“运营”。
  5. Convert the IEnumerabale<T> result to a list by calling the .ToList() extension method. 通过调用.ToList()扩展方法,将IEnumerabale<T>结果转换为列表。

This may not be the most efficient, and it doesn't cover all the properties you have in your original code, but it should at least get you going in the right direction. 这可能不是最有效的方法,并且不能涵盖原始代码中的所有属性,但至少可以使您朝正确的方向前进。 For example, if you wanted to get the "primaryRole" attribute, you'd simply add the following line in the new organisation() block: 例如,如果要获取“ primaryRole”属性,只需在new organisation()块中添加以下行:

orgPrimaryRole = (string)x.Attribute("primaryRole"), 

If you need the data from <DeptRoles> you can get that to, but it's a little more involved. 如果您需要来自<DeptRoles>的数据,则可以使用它,但是要涉及更多的内容。

If you prefer query syntax over method syntax, it would look like this: 如果您更喜欢查询语法而不是方法语法,它将看起来像这样:

listorgdata = (from x in xDoc.Root.Elements("dept")
               select new
                   {
                       orgOperationalStatus = (string)x.Attribute("operationalStatus"),
                       orgLegalStartDate = (from x1 in x.Elements("startDate")
                                            where (string)x1.Attribute("type") == "legal"
                                            select (string)x1).First(),
                        orgOperationalStartDate = (from x1 in x.Elements("startDate")
                                                   where (string)x1.Attribute("type") == "operational"
                                                   select (string)x1).First()
                    }).ToList();

If I Add CATALOG 如果我添加目录

<CATALOG>
<dept operationalStatus="active" primaryRole="Admin" depChangeDate="20130420">      
<startDate type="legal">20130401</startDate>
<endDate type="legal"></endDate>
<startDate type="operational">20130320</startDate>
<endDate type="operational"></endDate>  
<DeptRoles>         
<DeptRole name="Other dept" status="active">
<startDate type="legal">20130401</startDate>
<endDate type="legal"></endDate>
<startDate type="operational">20130320</startDate>
<endDate type="operational"/>
<isPrimary/>                
</DeptRole>
</DeptRoles>
</dept>
</CATALOG>

by using System.Xml.Linq; 通过使用System.Xml.Linq; You can get Your List : 你可以得到你的清单:

XElement myXML = XElement.Load(@"C:\Users\User\Desktop\myXML.xml");
var deptDescendantsList = (from ep in myXML.Descendants("dept")
                           select ep.Elements("startDate")).ToList();

I'm not sure how to create a query that fits your needs exactly. 我不确定如何创建完全适合您需求的查询。 Try to append this query to your needs. 尝试将此查询追加到您的需求。 http://msdn.microsoft.com/en-us/library/bb387061.aspx contains some info on linq2xml queries http://msdn.microsoft.com/zh-cn/library/bb387061.aspx包含有关linq2xml查询的一些信息

XmlReader xmlReader = XmlReader.Create(new StringReader(data));

XDocument d = XDocument.Load(xmlReader);

var startDates = from item in d.Root.Descendants()
                where item.Name == "startDate" && item.Parent.Name == "dept" && item.Parent.Attribute("deptid").Value == "anynumber"
                select item;

        // iterate over the startDates and do your magic

Try this : 尝试这个 :

var readSpecific = from a in xd.Descendants("departments") var readSpecific =来自xd.Descendants(“ departments”)中的a

                      select new
                      {

                          LegalStartDate = a.Element("dept").Elements("startDate").First(cc => cc.Attribute("type").Value == "legal").Value,
                          LegalEndDate = a.Element("dept").Elements("endDate").First(cc => cc.Attribute("type").Value == "legal").Value,

                          OperationalStartDate = a.Element("dept").Elements("startDate").First(cc => cc.Attribute("type").Value == "operational").Value,
                          OperationEndDate = a.Elements("dept").Elements("endDate").First(cc => cc.Attribute("type").Value == "operational").Value
                       };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM