2014-06-18 173 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 
         };