Предотвращение избыточности в документах XML - PullRequest
2 голосов
/ 24 марта 2010

Я работал с определенным XML, где не было избыточностей

<person>
  <eye>
    <eye_info>
       <eye_color>
       blue
       </eye_color>
    </eye_info>
  </eye>
  <hair>
    <hair_info>
       <hair_color>
       blue
       </hair_color>
    </hair_info>
  </hair>
</person>

Как вы можете видеть, под-тег eye-color в его названии ссылается на eye, поэтому избегать избыточности не было необходимости, я мог получить цвет eye в одной строке после загрузки XML в набор данных:

dataset.ReadXml(path);
value = dataset.Tables("eye_info").Rows(0)("eye_color");

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

Теперь, допустим, я должен прочитать XML-файлы в следующем формате:

<person>
  <eye>
    <info>
       <color>
       blue
       </color>
    </info>
  </eye>
  <hair>
    <info>
       <color>
       blue
       </color>
    </info>
  </hair>
</person>

Итак, если я попытаюсь назвать это так:

dataset.ReadXml(path);
value = dataset.Tables("info").Rows(0)("color");

Там будет избыточность, потому что я мог пойти только на один уровень выше, чтобы идентифицировать одно поле в XML с моим предыдущим методом, а «двусмысленность» на три уровня выше.

Существует ли практический способ безошибочно достичь одного поля с учетом всех вышеперечисленных (или хотя бы нескольких) полей?

- [EDIT] -

Я задал еще один вопрос, спрашивая, как я могу получить определенный узел с linq, проверить его .

Ответы [ 3 ]

4 голосов
/ 24 марта 2010

Вы также можете использовать Linq to XML (пространство имен System.Xml.Linq) и получать ваши данные примерно так:

string xml = @"<persons>
<person> 
  <eye> 
    <info> 
       <color>blue</color> 
    </info> 
  </eye> 
  <hair> 
    <info> 
       <color>blonde</color> 
    </info> 
  </hair> 
</person>
<person> 
  <eye> 
    <info> 
       <color>green</color> 
    </info> 
  </eye> 
  <hair> 
    <info> 
       <color>brown</color> 
    </info> 
  </hair> 
</person>
</persons>";

XDocument document = XDocument.Parse(xml);

var query = from person in document.Descendants("person")
            select new
            {
                EyeColor = person.Element("eye").Element("info").Element("color").Value,
                HairColor = person.Element("hair").Element("info").Element("color").Value
            };

foreach (var person in query)
    Console.WriteLine("{0}\t{1}", person.EyeColor, person.HairColor);
2 голосов
/ 24 марта 2010

Существует целый стандарт для запроса данных из XML-документа. Стандарт называется XPath, а C # имеет реализацию. Это не самая простая вещь для изучения из коробки, но это один из лучших методов извлечения данных из XML, который стоит изучить.

Здесь является примером.

РЕДАКТИРОВАТЬ: Я бы порекомендовал вам выяснить LINQ to XML, так как он более мощный, но если вы все еще хотите XPath, тогда ваш конкретный вопрос будет выглядеть примерно так (у меня нет VS на этом компьютере, поэтому я не смог проверить ) ...

XPathDocument doc = new XPathDocument(new StringReader(xmlString));
XPathNavigator nav = doc.CreateNavigator();

// Compile a standard XPath expression
XPathExpression expr = nav.Compile("/person/eye/eye_info/eye_color");
expr = nav.Compile("/catalog/cd/price");
XPathNodeIterator iterator = nav.Select(expr);

// Iterate on the node set
while (iterator.MoveNext())
{
   XPathNavigator nav2 = iterator.Current.Clone();
   Console.WriteLine(nav2.Value);
}
0 голосов
/ 24 марта 2010

Помните, что класс DataSet может понимать только XML, который можно преобразовать в форму реляционной базы данных. В частности, он не будет обрабатывать одну дочернюю «таблицу», которая имеет несколько родительских «таблиц». Примером этого является наличие элемента «информация» в качестве дочернего элемента - человека, волос и глаз.

...