none
парсить XML получить значение параметров RRS feed

  • Вопрос

  • <root>
    -<link val="Alfa Romeo" url="http://stores.ebay.de/atkgmbh/Alfa-Romeo-/_i.html?_fsub=2077125016&_sid=982877376&_trksid=p4634.c0.m322">
    <sub val="[086] Alfa 156 1,8L Benzin" url="http://stores.ebay.de/atkgmbh/086-Alfa-156-1-8L-Benzin-/_i.html?_fsub=2077126016&_sid=982877376&_trksid=p4634.c0.m322"/>
    <sub val="[215] Alfa Romeo 145 1.4l 1994" url="http://stores.ebay.de/atkgmbh/215-Alfa-Romeo-145-1-4l-1994-/_i.html?_fsub=4053423016&_sid=982877376&_trksid=p4634.c0.m322"/></link>
    </root>

    допустим есть такая XML. как составить список из тегов <sub> и прочитать параметр val и uri, не использовав регулярные выражения, только класс для работы с xml?

    • Изменено Magals 29 мая 2013 г. 9:24

Ответы

  • Magals,

    Начну с того (да, я педант), что представленный в самом первом сообщении текст не является xml. В xml знак & должен быть представлен как сущность &amp;. Любой xml-процессор, соответствующий стандарту, должен выдавать ошибку при парсинге этого текста.

    Но, полагаю, в исходном тексте на самом деле содержатся сущности &amp;, а на форуме представлен xml после их разрешения (resolve).

    Код почти правильный, только один цикл лишний. XmlDocument может находить узлы по всей иерархии, поэтому достаточно одной операции поиска-получения узлов:

    XmlNodeList subs = allxml.GetElementsByTagName("sub");  // можно так
    // XmlNodeList subs = allxml.SelectNodes("root/link/sub"); // или так
    
    foreach (XmlNode sub in subs)
    {
        list.Add(new Itemcar { nameCar = sub.Attributes["val"].Value, uricar = sub.Attributes["url"].Value });
    }

    Продолжу ворчать (я такой!). Официальный стиль проектирования рекомендует давать открытым свойствам класса имена в стиле PascalCase. То есть не nameCar и uricar, а NameCar и UriCar. Название класса, соответственно, должно быть ItemCar.

    А если учесть правила английского языка, то (тут я могу ошибаться), правильней будет CarItem. А в именах свойств незачем повторять аффикс Car, так как он уже есть в имени класса, поэтому вернее будет просто Name и Uri.

    • Помечено в качестве ответа Magals 30 мая 2013 г. 17:15

Все ответы

  • Самое простое это так:

    class Context { public string val; public string uri; } ....... //Основной код

    XElement xe = XElement.Load(@"C:\МойXML.xml");

    List<Context> Result = new List<Context>(); foreach (XElement x in (xe.FirstNode as XElement).Nodes() ) { if (x.Name == "sub") { Result.Add(new Context { val=x.Attribute("val").Value,uri=x.Attribute("url").Value}); } }




  • void XMLRead(string uri, List<Itemcar> list)
            {
                Stream stream =new WebClient().OpenRead(uri);
                StreamReader reader = new StreamReader(stream);
                XmlDocument allxml = new XmlDocument();
                allxml.LoadXml(reader.ReadToEnd());
    
                foreach (XmlNode x in allxml.GetElementsByTagName("link"))
                {
                    XmlDocument link = new XmlDocument();
                    link.LoadXml("<root>"+x.InnerXml+"</root>");
                    foreach (XmlNode it in link.GetElementsByTagName("sub"))
                    {
                        list.Add(new Itemcar { nameCar = it.Attributes["val"].InnerText, uricar = it.Attributes["url"].InnerText });
                    }
                }
            }

    C xElement не работал, поэтому чтение для меня становится сложноватым. Сделал немного по другому. Если есть критика, то готов выслушать. в основном мне не нравится как сделал с ("<root>"+x.InnerXml+"</root>"); для того что бы можно было загрузить код, может есть другой способо без этих вставок <root>/


    • Изменено Magals 29 мая 2013 г. 11:54
  • Скажу так. Если Вы используете .NET 3.0 и ниже, то можете пользоваться XmlDocument как классический DOM API, с внедрением LINQ с .NET 3.5 стало возможным использовать LINQ to XML, что позволило быстро и просто создавать документы XML и работать с ними. Если Вы хорошо знаете модель DOM XML и не хотите изучать LINQ to XML, то пожалуйста, пользуйтесь XmlDocument. Не вижу в этом ничего плохого
    • Изменено Higgs.Boson 29 мая 2013 г. 12:19
  • Magals,

    Начну с того (да, я педант), что представленный в самом первом сообщении текст не является xml. В xml знак & должен быть представлен как сущность &amp;. Любой xml-процессор, соответствующий стандарту, должен выдавать ошибку при парсинге этого текста.

    Но, полагаю, в исходном тексте на самом деле содержатся сущности &amp;, а на форуме представлен xml после их разрешения (resolve).

    Код почти правильный, только один цикл лишний. XmlDocument может находить узлы по всей иерархии, поэтому достаточно одной операции поиска-получения узлов:

    XmlNodeList subs = allxml.GetElementsByTagName("sub");  // можно так
    // XmlNodeList subs = allxml.SelectNodes("root/link/sub"); // или так
    
    foreach (XmlNode sub in subs)
    {
        list.Add(new Itemcar { nameCar = sub.Attributes["val"].Value, uricar = sub.Attributes["url"].Value });
    }

    Продолжу ворчать (я такой!). Официальный стиль проектирования рекомендует давать открытым свойствам класса имена в стиле PascalCase. То есть не nameCar и uricar, а NameCar и UriCar. Название класса, соответственно, должно быть ItemCar.

    А если учесть правила английского языка, то (тут я могу ошибаться), правильней будет CarItem. А в именах свойств незачем повторять аффикс Car, так как он уже есть в имени класса, поэтому вернее будет просто Name и Uri.

    • Помечено в качестве ответа Magals 30 мая 2013 г. 17:15
  • Higgs.Boson,

    Такой код:

    if (x.Name == "sub")

    - не комильфо! Как и предыдущем случае, работу нужно возлагать на класс, хорошо умеющий её делать. К тому же используя FirstNode мы получаем только первый узел, а в документе, наверняка, будет содержаться множество узлов link.

    Код можно написать проще:

    XElement xe = ...;
    
    var subs = xe.Elements("link").Elements("sub");
    
    foreach (var sub in subs)
    {
        list.Add(new CarItem { Name = sub.Attribute("val").Value, Uri = sub.Attribute("url").Value });
    }