了解与 linq 一起使用的 xml 个名称空间

Understand xml namespaces used with linq

我尝试从 xml 文件中获取信息,到目前为止,我非常擅长通过

进行导航
doc.Element("foo1").Element("foo2").Value

但现在我 运行 撞墙了,我认为这是因为命名空间。 我使用此代码片段从 xml doc:

中过滤特定部分
 XNamespace xmlns = "http://www.siemens.com/automation/Openness/SW/Interface/v4";
 IEnumerable<XElement> de =
      from el in doc.Descendants(xmlns + "Section")
      where el.Attribute("Name").Value == "Input"
      select el;

命名空间已给定,生成的 XElement 如下:

<Section Name="Input" xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v4">
  <Member Name="STARTTASTER" Datatype="Bool" Remanence="NonRetain" Accessibility="Public">
    <AttributeList>
      <BooleanAttribute Name="ExternalAccessible" SystemDefined="true">true</BooleanAttribute>
      <BooleanAttribute Name="ExternalVisible" SystemDefined="true">true</BooleanAttribute>
      <BooleanAttribute Name="ExternalWritable" SystemDefined="true">true</BooleanAttribute>
      <BooleanAttribute Name="UserVisible" Informative="true" SystemDefined="true">true</BooleanAttribute>
      <BooleanAttribute Name="UserReadOnly" Informative="true" SystemDefined="true">false</BooleanAttribute>
      <BooleanAttribute Name="UserDeletable" Informative="true" SystemDefined="true">true</BooleanAttribute>
    </AttributeList>
  </Member>
</Section>

这正是我想要的,我可以保存在 root

现在我用

var foo = root.Element(xmlns + "Section");
Console.WriteLine(foo);

我希望得到这个

 <Member Name="STARTTASTER" Datatype="Bool" Remanence="NonRetain" Accessibility="Public">
        <AttributeList>
          <BooleanAttribute Name="ExternalAccessible" SystemDefined="true">true</BooleanAttribute>
          <BooleanAttribute Name="ExternalVisible" SystemDefined="true">true</BooleanAttribute>
          <BooleanAttribute Name="ExternalWritable" SystemDefined="true">true</BooleanAttribute>
          <BooleanAttribute Name="UserVisible" Informative="true" SystemDefined="true">true</BooleanAttribute>
          <BooleanAttribute Name="UserReadOnly" Informative="true" SystemDefined="true">false</BooleanAttribute>
          <BooleanAttribute Name="UserDeletable" Informative="true" SystemDefined="true">true</BooleanAttribute>
        </AttributeList>
 </Member>

但我什么也没得到。 现在我的第一个问题是为什么,其次,我怎样才能达到预期的结果。

如果有nicer/more实用的方法我也很高兴。 我实际上想将值“STARTTASTER”存储到一个变量中。

请尝试以下解决方案。

我将你的 XML 保存为 e:\Temp\Aschenauer。xml 文件:

<Section Name="Input" xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v4">
    <Member Name="STARTTASTER" Datatype="Bool" Remanence="NonRetain" Accessibility="Public">
        <AttributeList>
            <BooleanAttribute Name="ExternalAccessible" SystemDefined="true">true</BooleanAttribute>
            <BooleanAttribute Name="ExternalVisible" SystemDefined="true">true</BooleanAttribute>
            <BooleanAttribute Name="ExternalWritable" SystemDefined="true">true</BooleanAttribute>
            <BooleanAttribute Name="UserVisible" Informative="true" SystemDefined="true">true</BooleanAttribute>
            <BooleanAttribute Name="UserReadOnly" Informative="true" SystemDefined="true">false</BooleanAttribute>
            <BooleanAttribute Name="UserDeletable" Informative="true" SystemDefined="true">true</BooleanAttribute>
        </AttributeList>
    </Member>
</Section>

c#

void Main()
{
    const string filename = @"e:\Temp\Aschenauer.xml";

    XDocument xdoc = XDocument.Load(filename);
    XNamespace ns = xdoc.Root.GetDefaultNamespace();

    var NameAttr = xdoc.Descendants(ns + "Member")
        .Attributes("Name").FirstOrDefault().Value;

    Console.WriteLine($"Name='{NameAttr}'");
}

输出

姓名='STARTTASTER'

要回答具体的 'why do I get nothing?' 部分,在您的代码中:

root.Element(xmlns + "Section")

root 是您从初始查询中获得的 Section 元素。上面的代码正在搜索名为 Section 第一个子元素 。有none,所以你得到null。您似乎要寻找的是第一个名为 Member:

的子元素
root.Element(xmlns + "Member")