Разбор XML с C # - PullRequest
       26

Разбор XML с C #

3 голосов
/ 15 февраля 2011

У меня есть XML-файл следующим образом:
XML file

Я загрузил файл XML: http://dl.dropbox.com/u/10773282/2011/result.xml. Это сгенерированный компьютером XML, поэтому вам может понадобиться просмотрщик / редактор XML.

Я использую этот код C #, чтобы получить элементы в CoverageDSPriv/Module/*.

using System;
using System.Xml;
using System.Xml.Linq;

namespace HIR {
  class Dummy {

    static void Main(String[] argv) {

      XDocument doc = XDocument.Load("result.xml");

      var coveragePriv = doc.Descendants("CoverageDSPriv"); //.First();
      var cons = coveragePriv.Elements("Module");

      foreach (var con in cons)
      {
        var id = con.Value;
        Console.WriteLine(id);
      }
    }
  }
}

Запустив код, я получаю этот результат.

hello.exe6144008016161810hello.exehello.exehello.exe81061hello.exehello.exe!17main_main40030170170010180180011190190012200200013hello.exe!107testfunctiontestfunction(int)40131505001460600158080216120120017140140018AA

Я ожидаю получить

hello.exe
61440
...

Однако я получаю только одну строку длинной строки.

  • Q1: Что может быть не так?
  • Q2: Как получить количество элементов в минусах? Я пытался cons.Count, но это не работает.
  • Q3: если мне нужно получить вложенное значение <CoverageDSPriv><Module><ModuleNmae>, я использую этот код:

    var coverPriv = doc.Descendants ("CoverageDSPriv"); //.Первый(); var cons = coverPriv.Elements ("Module"). Elements ("ModuleName");

Я могу с этим смириться, но если элементы глубоко вложены, я, возможно, захочу иметь прямой способ получить элементы. Есть ли другие способы сделать это?

ДОБАВЛЕНО

var cons = coveragePriv.Elements("Module").Elements();

решает эту проблему, но для NamespaceTable он снова выводит все элементы в одну строку.

hello.exe
61440
0
8
0
1
6
1
61810hello.exehello.exehello.exe81061hello.exehello.exe!17main_main40030170170010180180011190190012200200013hello.exe!107testfunctiontestfunction(int)40131505001460600158080216120120017140140018

Или, Linq to XML может быть лучшим решением, как этот пост .

Ответы [ 2 ]

4 голосов
/ 15 февраля 2011

Мне кажется, у вас есть только один элемент с именем Module, поэтому .Value просто возвращает вам InnerText всего этого элемента. Вы намеревались это вместо этого?

coveragePriv.Element("Module").Elements();

Это вернуло бы все дочерние элементы элемента Module, который, похоже, будет вашим после.

Обновление:

<NamespaceTable> является дочерним для <Module>, но вы, похоже, хотите обработать его аналогично <Module> в том, что вы хотите записать каждый дочерний элемент. Таким образом, один метод грубой силы должен был бы добавить еще один цикл для <NamespaceTable>:

foreach (var con in cons)
{
    if (con.Name == "NamespaceTable") 
    {
        foreach (var nsElement in con.Elements()) 
        {
            var nsId = nsElement.Value;
            Console.WriteLine(nsId);
        }
    }
    else
    {
        var id = con.Value;
        Console.WriteLine(id);
    }
}

В качестве альтернативы, возможно, вам лучше всего просто денормализовать их через .Descendents():

var cons = coveragePriv.Element("Module").Descendents();

foreach (var con in cons)
{
    var id = con.Value;
    Console.WriteLine(id);
}
1 голос
/ 15 февраля 2011

XMLElement.Value имеет неожиданные результаты.В XML с использованием .net вы действительно отвечаете за ручной обход дерева xml.Если элемент является текстовым, тогда value может возвращать то, что вы хотите, но если это другой элемент, то не так много.

Я сделал много разборов xml и обнаружил, что есть более эффективные способы обработки XML в зависимости от того, чтовы работаете с данными.

1) Вы можете посмотреть преобразования XSLT, если планируете выводить эти данные в виде текста, большего количества XML или HTML.Это отличный способ конвертировать данные в другой читаемый формат.Мы используем это, когда хотим отобразить наши метаданные на нашем веб-сайте в формате html.

2) Посмотрите на сериализацию XML.C # делает это очень просто, и это удивительно в использовании, потому что тогда вы можете работать с обычным объектом C # при использовании данных.У MS даже есть инструменты для создания класса серлизации из XML.Я обычно начинаю с этого, убираю его и добавляю свои настройки, чтобы все работало так, как я хочу.Лучший способ - десериализовать объект в XML и посмотреть, соответствует ли он тому, что у вас есть.

3) Попробуйте Linq to XML.Это позволит вам запрашивать XML, как если бы это была база данных.Обычно он немного медленнее, но если вам не нужна абсолютная производительность, он работает очень хорошо для минимизации вашей работы.

...