Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XPathSelectElement始终返回null_C#_Xml_Xpath - Fatal编程技术网

C# XPathSelectElement始终返回null

C# XPathSelectElement始终返回null,c#,xml,xpath,C#,Xml,Xpath,为什么使用XDocument.XPathSelectElement时此Xpath不起作用 Xpath: //Plugin/UI[1]/PluginPageCategory[1]/Page[1]/Group[1]/CommandRef[2] XML 使用名称空间时,XPath查询中也必须使用这些名称空间。XPath查询只对没有名称空间的元素有效(可以通过从XML中删除名称空间来验证这一点) 下面的示例显示了如何创建和传递命名空间管理器: var xml = ... XML from your p

为什么使用XDocument.XPathSelectElement时此Xpath不起作用

Xpath:

//Plugin/UI[1]/PluginPageCategory[1]/Page[1]/Group[1]/CommandRef[2]
XML


使用名称空间时,XPath查询中也必须使用这些名称空间。XPath查询只对没有名称空间的元素有效(可以通过从XML中删除名称空间来验证这一点)

下面的示例显示了如何创建和传递命名空间管理器:

var xml = ... XML from your post ...;

var xmlReader = XmlReader.Create( new StringReader(xml) ); // Or whatever your source is, of course.
var myXDocument = XDocument.Load( xmlReader );
var namespaceManager = new XmlNamespaceManager( xmlReader.NameTable ); // We now have a namespace manager that knows of the namespaces used in your document.
namespaceManager.AddNamespace( "prefix", "http://www.MyNamespace.ca/MyPath" ); // We add an explicit prefix mapping for our query.

var result = myXDocument.XPathSelectElement(
    "//prefix:Plugin/prefix:UI[1]/prefix:PluginPageCategory[1]/prefix:Page[1]/prefix:Group[1]/prefix:CommandRef[2]",
    namespaceManager
); // We use that prefix against the elements in the query.

Console.WriteLine(result); // <CommandRef ...> element is printed.
var xml=。。。XML从您的帖子。。。;
var xmlReader=xmlReader.Create(新StringReader(xml));//当然,不管你的消息来源是什么。
var myXDocument=XDocument.Load(xmlReader);
var namespaceManager=新的XmlNamespaceManager(xmlReader.NameTable);//我们现在有了一个名称空间管理器,它知道文档中使用的名称空间。
namespaceManager.AddNamespace(“前缀”http://www.MyNamespace.ca/MyPath" ); // 我们为查询添加了一个显式前缀映射。
var result=myXDocument.XPathSelectElement(
“//前缀:Plugin/prefix:UI[1]/前缀:PluginPageCategory[1]/前缀:Page[1]/前缀:Group[1]/前缀:CommandRef[2]”,
名称空间管理器
); // 我们对查询中的元素使用该前缀。
Console.WriteLine(结果);//元素已打印。

希望这能有所帮助。

有一种方法可以做到这一点,而无需对xpath进行任何更改。我找到的解决方案是在将XML解析到XDocument时删除名称空间

以下是一个例子:

var regex = @"(xmlns:?[^=]*=[""][^""]*[""])";
var myXDocument = XDocument.Parse(Regex.Replace("MyXmlContent", regex, "", RegexOptions.IgnoreCase | RegexOptions.Multiline))

既然名称空间消失了,操作起来就更容易了。

这可能是对@Cumbayah的帖子的评论,但我似乎什么都不能留下评论

您最好使用这样的方法,而不是使用XmlReader来获取名称表

var xml = ... XML from your post ...;
var myXDocument = XDocument.Parse(xml);
var namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("prefix", "http://www.MyNamespace.ca/MyPath");

var result = ...;

本例中最简单的方法是使用XPath轴和节点测试来选择元素的节点名称和位置。 您的XPath选择:

myXDocument.XPathSelectElement("//Plugin/UI[1]/PluginPageCategory[1]/Page[1]/Group[1]/CommandRef[2]", myXDocument.Root.CreateNavigator());
可轻松转换为:

myXDocument.XPathSelectElement("/child::node()[local-name()='Plugin']/child::node()[local-name()='UI'][position()=1]/child::node()[local-name()='PluginPageCategory'][position()=1]/child::node()[local-name()='Page'][position()=1]/child::node()[local-name()='Group'][position()=1]/child::node()[local-name()='CommandRef'][position()=2]");

无需创建XmlNamespaceManager并将其作为参数传递。

xpath查询中没有名称空间信息,这可能是原因所在。为了缩小范围,请尝试删除XML上的名称空间,看看是否会有结果?这可能是由于名称空间造成的-请检查从XML中删除名称空间是否会解决问题,如果可以,则需要设置名称空间管理器。@Cumbayah:是的,谢谢。但是现在我该如何正确处理名称空间?@Jean看到这篇文章“现在名称空间消失了”的可能重复,你可能没有一个格式良好的XML文档……好吧。。。它对我非常有效。请注意,当您无法更改xpath时,它会很有用。它并不是在所有情况下都能很好地工作,特别是在两个没有名称空间的元素完全相同的情况下。只想指出一个问题,即默认名称空间应该加前缀。即namespaceManager.AddNamespace(“,”)将使DefaultNamespace属性按预期设置为rigth,但XPathSelectElement不会使用它。误导!!!太棒了,这非常有效。名称空间应该很简单,但非常棘手,因此此解决方案非常有用。如果必须显式添加前缀/ns,则从XmlReader加载
名称表
有什么意义无论如何?我假设您这样做是因为您不知道文档用于所需名称空间的前缀。但是,这是否也意味着没有必要使用
NameTable
初始化
XmlNamespaceManager
?我只会从字符串中删除名称空间。如果您知道名称空间是唯一的。
myXDocument.XPathSelectElement("//Plugin/UI[1]/PluginPageCategory[1]/Page[1]/Group[1]/CommandRef[2]", myXDocument.Root.CreateNavigator());
myXDocument.XPathSelectElement("/child::node()[local-name()='Plugin']/child::node()[local-name()='UI'][position()=1]/child::node()[local-name()='PluginPageCategory'][position()=1]/child::node()[local-name()='Page'][position()=1]/child::node()[local-name()='Group'][position()=1]/child::node()[local-name()='CommandRef'][position()=2]");