在 .NET 中从 XML 文档中过滤元素的最简单方法

发布于 2025-01-05 08:43:47 字数 1142 浏览 0 评论 0原文

假设我有以下文档

<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>

,我只想要 ID 和值元素 -

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

如何使用 XDocument 和 LINQ 仅选择这些元素?

Let's say I have the following doc

<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>

and I just want the ID and value elements -

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

How could I select just these using XDocument and LINQ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

玻璃人 2025-01-12 08:43:47

使用 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);

prints:

<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));

Use linq-to-xml, the following code:

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);

prints:

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

If you don't need transformed XML, but just, say, dictionary of id -> value mapping, (storing value as int), you could do:

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));
(り薆情海 2025-01-12 08:43:47
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,其属性为 IdValue(均为字符串)。

您可以创建自己的 Setting 类型,并在投影中使用它,如果需要,还可以将“value”字符串值转换为整数。

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 
       });

This would produce an IEnumerable of an anonymous type, with properties Id and Value (both strings).

You could create your own Setting type, and use that in the projection instead, also converting the 'value' string value to an integer if required.

肤浅与狂妄 2025-01-12 08:43:47

我的第一个答案与其他答案非常相似,并且不太清楚,所以我将其删除。然而,我认为编写一些 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);

My first answer was very similar to the other answers, and wasn't as clear, so I removed it. However, I thought it would be a good exercise to write some linq that would generate the filtered XML when the desired elements were at any arbitrary depth. This is what I came up with:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文