如何使用Linq to XML动态查询命名空间

时间:2012-03-05 05:29:49

标签: vb.net linq-to-xml

我有290个组策略备份xml文件,我需要在单独的文件夹中枚举。

对于每个组策略备份xml文件,我需要查询策略设置。

之前看过组策略xml备份文件的任何人都知道他们是chock-a-block,充满了命名空间声明。

我想知道,使用Linq to XML,当我查询每个xml文件时,如何动态查询XML命名空间,然后将命名空间附加到Linq查询中以获取子节点/值?

以下是xml结构的一些示例。

  <User>
    <ExtensionData>
      <Extension xmlns:q1="http://www.microsoft.com/GroupPolicy/Settings/Scripts" xsi:type="q1:Scripts">
        <q1:Script>


    <ExtensionData>
      <Extension xmlns:q1="http://www.microsoft.com/GroupPolicy/Settings/IE" xsi:type="q1:InternetExplorerSettings">
        <q1:PreferenceMode>true</q1:PreferenceMode>


    <ExtensionData>
      <Extension xmlns:q2="http://www.microsoft.com/GroupPolicy/Settings/Registry" xsi:type="q2:RegistrySettings">
        <q2:Policy>
          <q2:Name>Disable changing accessibility settings</q2:Name>
          <q2:State>Enabled</q2:State>


    <ExtensionData>
      <Extension xmlns:q1="http://www.microsoft.com/GroupPolicy/Settings/DriveMaps" xsi:type="q1:DriveMapSettings">
        <q1:DriveMapSettings clsid="{8FDDCC1A-0C3C-43cd-A6B4-71A6DF20DA8C}">

我的初始代码如下:

Dim NS As XNamespace = "http://www.microsoft.com/GroupPolicy/Settings"
NodeValue = XDoc.Descendants(NS + NodeName).First().Value

正如你所看到的,我将面对几十个不同的命名空间,在这个阶段我甚至都不知道它们是什么。

我的最终任务是遍历290个目录,每个目录包含一个组策略xml备份文件。然后,我需要从备份文件中包含的每个设置中读取策略名称。

因为我不知道每个xml flie将包含哪些策略设置,所以我不知道在尝试读取xml值时我需要使用哪些命名空间。每个xml文件甚至可能包含多个名称空间。

如何动态读取Linq中的命名空间,以便我可以读取值?

由于

3 个答案:

答案 0 :(得分:0)

你关心这些命名空间吗?即,您是否区分它们并根据命名空间uri进行不同类型的处理?如果你不这样做(例如你只是展示某些东西),你可以这样做:

XDoc.Descendants().Where(e => e.Name.LocalName == "Extension")

无论命名空间如何,都应选择所有Extension元素。或者,如果您需要使用命名空间而不是硬编码来查询元素,您可以执行以下操作:

foreach(XElement extensionElement in XDoc.Descendants().Where(e => e.Name.LocalName == "Extension")
{
   var ns = extensionElement.Name.NamespaceName;
   Console.WriteLine(extensionElement(ns + "DriveMapSettings"));
}

答案 1 :(得分:0)

From e In XDoc.Descendants Group By e.Name.Namespace.NamespaceName应找到所有不同的命名空间,但未经测试。

答案 2 :(得分:0)

这是我最终的结果:

Dim ListOfNamespaces = z.Root.DescendantsAndSelf.Attributes().Where(Function(a) a.IsNamespaceDeclaration).GroupBy(Function(a) If(a.Name.[Namespace] = XNamespace.None, [String].Empty, a.Name.LocalName), Function(a) XNamespace.[Get](a.Value)).ToDictionary(Function(g) g.Key, Function(g) g.First())