С# LINQ to XML — не найти элементы или потомки

У меня возникли проблемы с использованием LINQ to XML для чтения моего XML-файла. Я приложил часть схемы xml.

 <?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mstns="http://tempuri.org/sdnList.xsd" xmlns="http://tempuri.org/sdnList.xsd" elementFormDefault="qualified" targetNamespace="http://tempuri.org/sdnList.xsd" id="sdnList">
  -<xs:element name="sdnList"> 
    -<xs:complexType> 
      -<xs:sequence> 
        -<xs:element name="publshInformation" maxOccurs="1"> 
         -<xs:complexType> 
          -<xs:sequence> 
             <xs:element name="Publish_Date" maxOccurs="1" minOccurs="0" type="xs:string"/> 
            <xs:element name="Record_Count" maxOccurs="1" minOccurs="0" type="xs:int"/> 
           </xs:sequence> 
          </xs:complexType> 
         </xs:element> 
       -<xs:element name="sdnEntry" maxOccurs="unbounded"> 
         -<xs:complexType> 
           -<xs:sequence> 
              <xs:element name="uid" type="xs:int"/> 
              <xs:element name="firstName" minOccurs="0" type="xs:string"/> 
              <xs:element name="lastName" type="xs:string"/> 
              <xs:element name="title" minOccurs="0" type="xs:string"/> 
              <xs:element name="sdnType" type="xs:string"/> 
              <xs:element name="remarks" minOccurs="0" type="xs:string"/> 

              ....CONTINUES FROM HERE

Код, который я использую, выглядит следующим образом.

            XDocument doc = XDocument.Load("c:/OFACTemp/sdn.xml");

            var sdnEntry = from item in doc.Root.Descendants("sdnEntry")
                           select new
                           {
                               uid = item.Element("uid").Value,
                               firstName = item.Element("firstName").Value
                           };

            string test = "";
            foreach (var p in sdnEntry)
                test = "Id: " + p.uid + " First Name: " + p.firstName;  

Когда я прерываю код, документ загружается нормально, и я вижу правильные данные. Doc.Root заполнен, но Descendants, кажется, ничего не имеет. Затем, дойдя до моего оператора foreach, sdnEntry не дает никаких результатов. Это кажется таким простым, но я не могу понять, почему я не могу ничего выбрать. Я также пытался использовать элементы вместо потомков и тот же результат. Конечный результат. Мне нужно взять XML и создать объекты C#.

Кроме того, возникает побочный вопрос: как будет обрабатываться sdnEntry, если некоторые sdnEntry имеют, например, имя, а другие — нет? Если для sdEntry не существует имени, то тег элемента firstName даже не существует в XML-файле. Любая помощь будет принята с благодарностью.

Вот образец xml.

<?xml version="1.0" standalone="true"?>
-<sdnList xmlns="http://tempuri.org/sdnList.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
  -<publshInformation> 
     <Publish_Date>05/16/2013</Publish_Date> 
     <Record_Count>5493</Record_Count>
   </publshInformation> 
   -<sdnEntry> 
     <uid>10</uid> 
     <lastName>ABASTECEDORA NAVAL Y INDUSTRIAL, S.A.</lastName> 
     <sdnType>Entity</sdnType> 
    -<programList> 
       <program>CUBA</program> 
     </programList> 
    -<akaList> 
      -<aka> 
         <uid>4</uid> 
         <type>a.k.a.</type> 
         <category>strong</category> 
         <lastName>ANAINSA</lastName> 
       </aka> 
     </akaList> 
    -<addressList> 
      -<address> 
         <uid>7</uid> 
         <country>Panama</country> 
         </address> 
     </addressList>  
   </sdnEntry>

person user2417864    schedule 24.05.2013    source источник
comment
Ваш код ищет элементы XML с именем sdnEntry, тогда как в вашем XML есть элементы с именем element с атрибутами с именем name, которые имеют значения sdnEntry   -  person paul    schedule 24.05.2013
comment
Я понятия не имею, почему, но когда я вижу linq to xml, у меня возникает то же чувство, что и при просмотре плохого фильма ужасов.   -  person Jonesopolis    schedule 24.05.2013
comment
Можете ли вы показать часть XML? Это только XSD...   -  person sexta13    schedule 24.05.2013
comment
@paul, так как мне прочитать и вытащить uid и имя? sexta, вот одна sdnEntry из xml. Извините, я должен был опубликовать это раньше. У этого показанного sdnEntry нет имени, тогда как у других sdnEntry оно есть.   -  person user2417864    schedule 24.05.2013
comment
‹?xml version=1.0 standalone=true?› -‹sdnList xmlns=tempuri.org/sdnList.xsd xmlns:xsi=w3.org/2001/XMLSchema-instance› -‹publshInformation › ‹Publish_Date›16/05/2013‹/Publish_Date› ‹Record_Count›5493‹/Record_Count› ‹/publshInformation› -‹sdnEntry› ‹uid›10‹/uid› ‹lastName›ABASTECEDORA NAVAL Y INDUSTRIAL, SA‹/lastName› ‹sdnType›Entity‹/sdnType› -‹programList› ‹program›CUBA‹/program› ‹/programList› +‹akaList›-   -  person user2417864    schedule 24.05.2013
comment
Извините, не удалось получить xml для публикации в лучшем формате.   -  person user2417864    schedule 24.05.2013
comment
Я разместил отформатированный xml в своем исходном сообщении.   -  person user2417864    schedule 24.05.2013


Ответы (3)


Вам нужно принять во внимание пространство имен по умолчанию, с LINQ to XML вы делаете это, объявляя

XNamespace df = "http://tempuri.org/sdnList.xsd";

или, альтернативно, динамически с

XNamespace df = doc.Root.Name.Namespace;

тогда вам нужно использовать объект XNamespace для создания XNames в вашем запросе, например.

       var sdnEntry = from item in doc.Root.Descendants(df + "sdnEntry")
                       select new
                       {
                           uid = (string)item.Element(df + "uid"),
                           firstName = (string)item.Element(df + "firstName")
                       };
person Martin Honnen    schedule 26.05.2013

удаление этой части из верхней строки сработало для меня. Я понятия не имею, почему это так. но это сработало. xmlns:mstns="http://tempuri.org/sdnList.xsd"

person Mushariar    schedule 05.03.2015

В итоге я использовал XmlSerializer для решения своей проблемы. После того, как файл xml был загружен через FTP, я использовал следующий код. Затем я смог использовать C# для заполнения своих объектов C#.

FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();               
StreamReader sreader = new StreamReader(responseStream);
string xmlString = sreader.ReadToEnd();        
XmlSerializer serializer = new XmlSerializer(typeof(sdnList));
TextReader reader = new StringReader(xmlString); 
sdnList = (sdnList)serializer.Deserialize(reader);
person user2417864    schedule 11.06.2013