2013-02-04 35 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>标签未关闭...