Использование XmlReader для чтения XML

У меня возникли проблемы с использованием XmlReader для чтения файла XML. Я могу нормально открывать и закрывать файл (я думаю), но когда дело доходит до разбора нужной мне информации, я немного теряюсь. Вот часть файла, который мне нужно разобрать:

<?xml version="1.0" encoding="UTF-8"?>
<database name="Dictionary">
  <data>
    <Translations>
      <Translation UniversalAbbv="Enu" lang="en" localization="US" unicode="0">
        <Set>
          ...
        </Set>
        <Set>
          ...
        </Set>
        <Set>
          <CaseSensitive value="0" />
          <Enums translate="1">
            <Enum_Entry ENUM_H="STOPRUN_STOP" EnumID="0" EnumString="Stop" SetID="160" />
            <Enum_Entry ENUM_H="STOPRUN_RUN" EnumID="1" EnumString="Run" SetID="160" />
            <Enum_Entry ENUM_H="STOPRUN_HOLD " EnumID="2" EnumString="Hold" SetID="160" />
          </Enums>
          <IncludeFiles_cs name="CSFile" value="StopRun.cs" />
          <IncludeFiles_h name="Header" value="NULL" />
          <IncludeFiles_java name="Java" value="NULL" />
          <SetID value="160" />
          <SetName value="Stop Run" />
          <TwoSet ENUM_H="STOPRUN_ENUM_SET" />
        </Set>
        <Set>
          ...
        </Set>
   </Translation>
  </Translations>
  </data>
</database>

Мне нужно найти где EnumID="0" или EnumID="1" (или "STOPRUN_STOP" или "STOPRUN_RUN") и соответственно вытащить строки "Stop" или "Run". Вот что у меня есть для кода:

static class Dictionary
{
    static private XmlReader Reader = null;

    static public void Open()
    {
        XML_Generator.Dictionary.Reader = XmlReader.Create(XML_Generator.Program.DictionaryFilename);
    }

    static public void Close()
    {
        XML_Generator.Dictionary.Reader.Close();
    }

    static public void Read()
    {
        while (Reader.Read())
        {
            Trace.TraceInformation(XML_Generator.Dictionary.Reader.ReadElementContentAsString()); // <-- This throw an error. :(
        }
    }
}

Я знаю, что это немного, но я немного потерялся в том, куда идти с этим. Любая помощь будет оценена по достоинству. Спасибо.


person Jim Fell    schedule 08.11.2011    source источник
comment
Есть ли причина, по которой вы используете XMLReader вместо LINQ или даже XMLDocument?   -  person Alex Mendez    schedule 08.11.2011
comment
Обычно я читаю набор данных, а затем индексирую его, чтобы найти интересующие меня значения. Любопытно посмотреть, как это могут сделать другие.   -  person GodsCrimeScene    schedule 08.11.2011
comment
@AlexMendez: мне никогда раньше не приходилось анализировать XML-файл. Является ли LINQ классом .NET?   -  person Jim Fell    schedule 08.11.2011
comment
@timmy: Как используется набор данных? Можно ссылку на пример?   -  person Jim Fell    schedule 08.11.2011
comment
LINQ — это интегрированный в язык запрос, который является частью .net 3.5 и выше. Это позволяет вам запрашивать ваш xml таким же образом, как и сервер sql. Вот несколько примеров: msdn.microsoft.com/en-us/library/bb397965 .aspx и msdn.microsoft.com/en-us/library /bb387061.aspx   -  person Alex Mendez    schedule 09.11.2011


Ответы (2)


Возможно, вы захотите взглянуть на XpathNavigator. Его синтаксис действительно прост в использовании, намного проще, чем делать это с помощью XMLReader.

Все, что вам нужно сделать, чтобы получить элемент EnumID="1", это //Enums/Enum_Entry[@EnumID=1]

person Ron Sijm    schedule 08.11.2011
comment
XPathNavigator кажется намного проще в использовании. С тех пор я узнал, что мне нужно использовать "STOPRUN_ENUM_SET" для получения атрибутов "Stop" и «Выполнить» из XML, который я опубликовал. Есть ли способ сделать это с помощью XPathNavigator? - person Jim Fell; 09.11.2011
comment
STOPRUN_ENUM_SET? судя по вашему примеру это не имеет особого смысла. Я думаю, вы имеете в виду STOPRUN_STOP? //Enum_Entry[@ENUM_H="STOPRUN_STOP"] в любом случае, если вы не хотите уже кодировать все, вы можете возиться с запросами по адресу: ‹mizar.dk/XPath/Default.aspx› и посмотрите, какой из них будет выбран. - person Ron Sijm; 09.11.2011
comment
Вот выражение, которое у меня есть до сих пор, но оно ничего не извлекает из файла XML: Translations/Translation/Set/TwoSet[@ENUM_H='STOPRUN_ENUM_SET']/../Enums/Enum_Entry[@EnumID < 2] - person Jim Fell; 09.11.2011
comment
//Translations/Translation/Set/TwoSet[@ENUM_H='STOPRUN_ENUM_SET'] по крайней мере извлекает весь набор... однако в вашем примере xml вы не указали данные для элемента TwoSet. Во всяком случае, только //TwoSet делает то же самое. Вам не нужно начинать с корневого узла, если вам от него ничего не нужно. - person Ron Sijm; 09.11.2011
comment
Ладно, думаю, я понял. Спасибо за помощь! //Set/TwoSet[@ENUM_H='STOPRUN_ENUM_SET']/../Enums/Enum_Entry[@EnumID<2] - person Jim Fell; 09.11.2011

Вот пример чтения XML-файла с помощью XML Reader

   int intCount = 0;
    XmlReaderSettings objSettings = new XmlReaderSettings();
    objSettings.IgnoreWhitespace = true;
    objSettings.IgnoreComments = true;
    string booksFile = Server.MapPath("books.xml");
    using (XmlReader objReader = XmlReader.Create(booksFile, objSettings))
    {
        while (objReader.Read())
        {
            if (objReader.NodeType == XmlNodeType.Element && "Book" == objReader.LocalName)
            {
                 intCount++;
            }
            if (objReader.NodeType ==XmlNodeType.Text )
            {
                Response.Write("<BR />" + objReader.Value);
            }
        }
    }
    Response.Write(String.Format("<BR /><BR /><BR /><b> Total {0} books.</b>", intCount));
person Jayesh Sorathia    schedule 03.07.2012