2013-02-04 39 views
1

我的XML的結構如下:如何通過LINQ to XML獲得間接後代節點?

<?xml version="1.0"?> 
<NidanArchiveDS> 
<xs:schema id="NidanArchiveDS" targetNamespace="http://tempuri.org/NidanArchiveDS.xsd" xmlns:mstns="http://tempuri.org/NidanArchiveDS.xsd" xmlns="http://tempuri.org/NidanArchiveDS.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified"> 
<xs:element name="NidanArchiveDS" msdata:IsDataSet="true" msdata:Locale="ru-RU"> 
    <xs:complexType> 
    <xs:choice minOccurs="0" maxOccurs="unbounded"> 
     <xs:element name="Settings"> 
     <xs:complexType> 
      <xs:attribute name="ContentTypeName" form="unqualified" type="xs:string" use="required" /> 
      <xs:attribute name="ListName" form="unqualified" type="xs:string" use="required" /> 
      <xs:attribute name="DocTypeFieldName" form="unqualified" type="xs:string" /> 
      <xs:attribute name="DocNumberFieldName" form="unqualified" type="xs:string" /> 
      <xs:attribute name="DOcDateFieldName" form="unqualified" type="xs:string" /> 
     </xs:complexType> 
     </xs:element> 
    </xs:choice> 
    </xs:complexType> 
    <xs:unique name="Constraint1" msdata:PrimaryKey="true"> 
    <xs:selector xpath=".//mstns:Settings" /> 
    <xs:field xpath="@ContentTypeName" /> 
    <xs:field xpath="@ListName" /> 
    </xs:unique> 
</xs:element> 
</xs:schema> 
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> 
<NidanArchiveDS xmlns="http://tempuri.org/NidanArchiveDS.xsd"> 
    <Settings diffgr:id="Settings1" msdata:rowOrder="0" ContentTypeName="CONTENTTYPE 1" ListName="Заявки на оплату" DocTypeFieldName="Имя11" DocNumberFieldName="Имя22" DOcDateFieldName="Имя33" /> 
    <Settings diffgr:id="Settings2" msdata:rowOrder="1" ContentTypeName="CONTENTTYPE 2" ListName="LST" DocTypeFieldName="Имя44" DocNumberFieldName="Имя" DOcDateFieldName="Имя5555" /> 

</NidanArchiveDS> 

下面有我的獲取設置與ContentTypeName = 「CONTENTTYPE 2」

docNameFieldName = (from xn in nidanarchiveSettings.Descendants(System.Xml.Linq.XName.Get("Settings")) 
                 where xn.Attribute(System.Xml.Linq.XName.Get("ContentTypeName")).Value == "CONTENTTYPE 2" 
                 && xn.Attribute(System.Xml.Linq.XName.Get("ListName")).Value == "LST" 
                 select xn.Attribute(System.Xml.Linq.XName.Get("DocTypeFieldName")).Value).SingleOrDefault(); 

查詢,但它給了我一個空字符串。我想知道如何以正確的風格編寫查詢來獲得此屬性。

回答

1

你忘了命名空間:

XDocument xdoc = XDocument.Load(path_to_xml); 
XNamespace ns = "http://tempuri.org/NidanArchiveDS.xsd"; 

var docNameFieldName = 
    (from s in xdoc.Descendants(ns + "Settings") 
    where (string)s.Attribute("ContentTypeName") == "CONTENTTYPE 2" && 
      (string)s.Attribute("ListName") == "LST" 
    select (string)s.Attribute("DocTypeFieldName")).SingleOrDefault(); 

也不要使用節點Value財產。只需將其轉換爲字符串(或其他類型),而不是在缺少某個節點時引發異常。

+1

哇!現在我的查詢就像一個魅力! – user216652

0

你可以去拉姆達路線有:

var docNameFieldName = xdoc.Descendants("Settings") 
.First(sett => sett.Attribute("ContentTypeName") == "CONTENTTYPE 2") 
.Attribute("DocTypeFieldName").Value; 

而且,你可能剛剛公佈的部分XML片段,但你的<diffgr:diffgram>標籤未關閉...