Самый простой способ отфильтровать элементы из XML-документа в .NET - PullRequest
2 голосов
/ 15 февраля 2012

Допустим, у меня есть следующий документ

<sets version="2.0">
  <setting>
    <id>set1</id>
    <value>80</value>
    <label>EVersion</label>
    <type>Val</type>
    <format>R</format>
    <bits>
      <addr>0</addr>
      <startBit>0</startBit>
      <bitWidth>8</bitWidth>
    </bitspec>
  </setting>
  <setting>
    <id>set3</id>
    <value>50</value>
    <label>GVersion</label>
    <type>Bin</type>
    <format>R</format>
    <bits>
      <addr>0</addr>
      <startBit>0</startBit>
      <bitWidth>8</bitWidth>
    </bitspec>
  </setting>
  </sets>

, и я просто хочу элементы идентификатора и значения -

<sets version="2.0">
  <setting>
    <id>set1</id>
    <value>80</value>
  </setting>
  <setting>
    <id>set3</id>
    <value>50</value>
  </setting>
  </sets>

Как я могу выбрать только эти, используя XDocument и LINQ?

Ответы [ 3 ]

2 голосов
/ 15 февраля 2012

Используйте linq-to-xml, следующий код:

var xml_str = @"<sets version=""2.0"">
  <setting>
    <id>set1</id>
    <value>80</value>
    <label>EVersion</label>
    <type>Val</type>
    <format>R</format>
    <bits>
      <addr>0</addr>
      <startBit>0</startBit>
      <bitWidth>8</bitWidth>
    </bits>
  </setting>
  <setting>
    <id>set3</id>
    <value>50</value>
    <label>GVersion</label>
    <type>Bin</type>
    <format>R</format>
    <bits>
      <addr>0</addr>
      <startBit>0</startBit>
      <bitWidth>8</bitWidth>
    </bits>
  </setting>
  </sets>";

var doc = XDocument.Parse(xml_str);

var settings = new XElement("sets",
    from setting in doc.Element("sets").Elements("setting")
    select new XElement("setting", setting.Element("id"), setting.Element("value")));

Console.WriteLine(settings);

печатает:

<sets>
  <setting>
    <id>set1</id>
    <value>80</value>
  </setting>
  <setting>
    <id>set3</id>
    <value>50</value>
  </setting>
</sets>

Если вам не нужен преобразованный XML, а просто, скажем, словарьid -> value отображение, (сохраняя value как int), вы можете сделать:

var doc = XDocument.Parse(xml_str);
var settings_dict = doc.Element("sets").Elements("setting").ToDictionary(s => s.Element("id").Value, s => Convert.ToInt32(s.Element("value").Value));
2 голосов
/ 15 февраля 2012
var xdoc = XDocument.Load(@"c:\myxml.xml");

var settings = 
    xdoc.Element("sets").Elements("setting")
    .Select(s => new 
       { 
         Id = s.Element("id").Value, 
         Value = s.Element("value").Value 
       });

Это приведет к созданию IEnumerable анонимного типа со свойствами Id и Value (обе строки).

Вы можете создать свой собственный тип Setting и использоватьчто вместо этого в проекции также преобразуется строковое значение 'value' в целое число, если требуется.

0 голосов
/ 15 февраля 2012

Мой первый ответ был очень похож на другие ответы и был не так ясен, поэтому я удалил его. Однако я подумал, что было бы неплохо написать некоторое linq, которое генерировало бы отфильтрованный XML, когда желаемые элементы были на любой произвольной глубине. Вот что я придумал:

Func<XElement, XElement> f = null; 
f = e => e.Name == "id" || e.Name == "value" ? e : //on a match, return the node
    new[] { new XElement(e.Name, e.Elements().Select(f)) } //else recurse
    .FirstOrDefault(y => y.Elements().Any()); //keeping subtrees with matches

XElement resultXmlElement = f(XDocument.Parse(yourXmlString).Root);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...