C# 无法让 XmlDocument.SelectNodes 检索我的任何节点?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12607895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:53:05  来源:igfitidea点击:

Can't get XmlDocument.SelectNodes to retrieve any of my nodes?

c#.netxmlxpathxmldocument

提问by Earlz

I'm trying to parse an XML document. The document in question is an AppxManifest file.

我正在尝试解析 XML 文档。有问题的文档是 AppxManifest 文件。

An example document looks like this:

示例文档如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:build="http://schemas.microsoft.com/developer/appx/2012/build" IgnorableNamespaces="build">
  <Identity Name="uytury" Publisher="hygj" Version="1.0.0.12" ProcessorArchitecture="neutral" />
  <Properties>
    <DisplayName>jhjj</DisplayName>
    <PublisherDisplayName>bhhjb</PublisherDisplayName>
    <Logo>Assets\StoreLogo.png</Logo>
  </Properties>
  <Prerequisites>
    <OSMinVersion>6.2.1</OSMinVersion>
    <OSMaxVersionTested>6.2.1</OSMaxVersionTested>
  </Prerequisites>
  <Resources>
    <Resource Language="EN" />
  </Resources>
  <Applications>
    <Application Id="App" Executable="gfg.exe" EntryPoint="gfg.App">
      <VisualElements DisplayName="fdsf" Logo="Assets\Logo.png" SmallLogo="Assets\SmallLogo.png" Description="gfdsg" ForegroundText="light" BackgroundColor="#2672EC">
        <DefaultTile ShowName="allLogos" WideLogo="Assets\WideLogo.png" ShortName="gfdsg" />
        <SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="#2672EC" />
        <InitialRotationPreference>
          <Rotation Preference="portrait" />
          <Rotation Preference="landscape" />
          <Rotation Preference="portraitFlipped" />
          <Rotation Preference="landscapeFlipped" />
        </InitialRotationPreference>
      </VisualElements>
      <Extensions>
        <Extension Category="windows.search" />
        <Extension Category="windows.shareTarget">
          <ShareTarget>
            <DataFormat>Text</DataFormat>
          </ShareTarget>
        </Extension>
      </Extensions>
    </Application>
  </Applications>
  <build:Metadata>
    <build:Item Name="TargetFrameworkMoniker" Value=".NETCore,Version=v4.5" />
    <build:Item Name="VisualStudio" Version="11.0" />
    <build:Item Name="OperatingSystem" Version="6.2.9200.16384 (win8_rtm.120725-1247)" />
    <build:Item Name="Microsoft.Build.AppxPackage.dll" Version="11.0.50727.1" />
    <build:Item Name="Microsoft.Windows.UI.Xaml.Build.Tasks.dll" Version="11.0.50727.1" />
  </build:Metadata>
</Package>

I try to parse it like so:

我尝试像这样解析它:

var xml=new XmlDocument();
xml.Load(myfile);
var mgr=new XmlNamespaceManager(xml.NameTable);
mgr.AddNamespace("", "http://schemas.microsoft.com/appx/2010/manifest");
var nodes=xml.SelectNodes("Applications");

However, after I execute this, nodeswill never contain anything. The xml document is loaded and such though. using SelectNodes("//*")returns every node as expected. What is my problem here?

但是,在我执行此操作后,nodes将永远不会包含任何内容。xml 文档已加载等等。usingSelectNodes("//*")按预期返回每个节点。我这里有什么问题?

I've also tried many variations on that XPath query such as

我还尝试了该 XPath 查询的许多变体,例如

  • /Package/Applications/Application
  • Applications/Application
  • Applications/*
  • /Package/Applications/Application
  • Applications/Application
  • Applications/*

Nothing appears to retrieve the single node though. Ideally, I'd like for nodes to contain all of the Applicationnodes

虽然似乎没有检索单个节点。理想情况下,我希望节点包含所有Application节点

采纳答案by aiodintsov

You have to use xml namespace specifically to select them. consider

您必须专门使用 xml 命名空间来选择它们。考虑

"//*[local-name()='Applications']/*[local-name()='Application']"    

in your case this code may also work well:

在您的情况下,此代码也可能运行良好:

var doc = new XmlDocument();
doc.LoadXml(xml);
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("a", "http://schemas.microsoft.com/appx/2010/manifest");
var nodes = doc.SelectNodes("//a:Applications/a:Application",nsmgr);

回答by Andreas Rehm

You might need to read this

你可能需要阅读这个

Here's your code:

这是你的代码:

var xml = new XmlDocument();
xml.Load("myXMLFile1.xml");
var mgr = new XmlNamespaceManager(xml.NameTable);
mgr.AddNamespace("", "http://schemas.microsoft.com/appx/2010/manifest");
XmlNode root = xml.DocumentElement;
var nodes = root.SelectNodes("//*[local-name()='Applications']/*[local-name()='Application']");

回答by Alexei Levenkov

You need to specify prefixes for namespaces in NamespaceManager and XPaths. Note that prefixes does not need to match anything except between your XPath and your namespace manager*.

您需要在 NamespaceManager 和 XPaths 中为命名空间指定前缀。请注意,除了 XPath 和命名空间管理器 * 之外,前缀不需要匹配任何内容。

var xml=new XmlDocument();
xml.Load(myfile);
var mgr=new XmlNamespaceManager(xml.NameTable);
mgr.AddNamespace("a", "http://schemas.microsoft.com/appx/2010/manifest");
mgr.AddNamespace("bar", "http://schemas.microsoft.com/developer/appx/2012/build");
var nodes=xml.SelectNodes("//a:Applications", mgr);

And as pointed out by other answers XPath that accepts any namespace is another option.

正如其他答案所指出的,接受任何命名空间的 XPath 是另一种选择。

*) I.e. in your particular sample there are 2 namespaces "default" (note that default prefix is not the same as empty namespace) and "build". So when you define your namespace manager you need to specify a prefix for each of the namespace (if you need to target nodes in both), but prefixes can be arbitrary strings (valid for prefixes but not empty). I.e. use "a" for "default" namespace and "bar" for namespace that mapped to "build" in the XML.

*) 即在您的特定示例中,有 2 个命名空间“默认”(请注意,默认前缀与空命名空间不同)和“构建”。因此,当您定义命名空间管理器时,您需要为每个命名空间指定一个前缀(如果您需要在两者中定位节点),但前缀可以是任意字符串(对前缀有效但不为空)。即使用“a”表示“默认”命名空间,“bar”表示映射到 XML 中“build”的命名空间。

回答by ajeh

Not in this particular case, but in general, if the namespace URN in the actual XML is not exactly the same as one used to add a namespace to a namespace manager (example: missing a trailing slash), and a prefix is specified in XPath, the query may return null.

不是在这种特殊情况下,但一般来说,如果实际 XML 中的命名空间 URN 与用于向命名空间管理器添加命名空间的命名空间不完全相同(例如:缺少尾部斜杠),并且在 XPath 中指定了前缀,查询可能返回null

If namespace URN in the XML is not reliable, syntax

如果 XML 中的命名空间 URN 不可靠,语法

"//*[local-name()='tag']" 

will work.

将工作。