2014-06-18 176 views
0

我有以下XML文件。我正在尝试读取dept元素的startDate节点,但不想读取其他任何子元素(如“DeptRoles”)的“startDate”节点。阅读XML节点

<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> 

这是我的C#代码。这段代码也得到了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; 
    } 

回答

0

如果我加入目录

<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> 

使用System.Xml.Linq的;你可以得到你的清单:

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

我该如何知道这个开始日期是否是合法的操作类型。如果我将deptid = anynumber添加到dept节点,可以请修改此查询。如何使用这个Lin2Xml查询来获取例如deptid = anynumber的startDate元素 – user3202862

0

我不知道如何创建一个完全符合你的需求的查询。 尝试将此查询追加到您的需求。 http://msdn.microsoft.com/en-us/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 
1

我会使用LINQ到XML(如其他人所说)。以下是与您发布的代码有点相符的示例代码 - 下面是对代码的解释。

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; 
}  

上述代码的第一件事是XML加载到与所述XDocument.Parse方法一个XDocument。

查询然后解析XML文档并返回填充的organization对象的列表。它是这样的。

  1. 获取所有<dept>元素(以及子元素)。
  2. 使用每个<dept>元素,创建一个organisation的新实例,并将“operationalStatus”属性的值分配给organisationoperationalStatus属性。 cast会优雅地处理指定属性不存在的情况。
  3. 对于合法开始日期,我们对<dept>元素的<startDate>子元素执行查询,将第一个具有“type”属性等于“legal”的元素作为开始日期。
  4. 对于运营开始日期,我们对3号进行类似的查询,除了它正在寻找“运营”。
  5. 通过调用.ToList()扩展方法将IEnumerabale<T>结果转换为列表。

这可能不是最有效的,它不包括你在原始代码中的所有属性,但它至少应该让你朝着正确的方向前进。例如,如果你想获得“primaryRole”属性,你只需添加以下行new organisation()块:

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

如果需要从<DeptRoles>数据,你可以得到的,但它是一个多一点参与。

如果你喜欢查询语法在方法的语法,它应该是这样的:

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(); 
0

试试这个:

VAR readSpecific =从在xd.Descendants( “部门”)

     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 
         };