【问题标题】:Why XPath expression doesn't return any results in C# but it does outside C#?为什么 XPath 表达式在 C# 中不返回任何结果,但在 C# 之外返回?
【发布时间】:2009-07-08 19:58:46
【问题描述】:

我正在为 Excel 工作表开发 Open XML 文档格式。

var nodeList = WorksheetXml.SelectNodes(@"//c[child::f]");

它应该返回所有带有公式的行,但它不返回任何内容。 Oxygen Editor 上的相同 xml,当应用相同的 xpath 表达式时,会返回所有这些。

我正在复制 WorksheetXml 内部 xml 以确保内容相同...您知道为什么 C# 无法按预期方式工作吗?


编辑:命名空间问题

我写了这个:

var manager = new XmlNamespaceManager(WorksheetXml.NameTable);
manager.AddNamespace(string.Empty, @"http://schemas.openxmlformats.org/spreadsheetml/2006/main");
manager.AddNamespace("r", @"http://schemas.openxmlformats.org/officeDocument/2006/relationships");

var nodeList = WorksheetXml.SelectNodes(@"//c[child::f]", manager);

它没有工作,我认为这不是命名空间的问题。

【问题讨论】:

  • btw, "//c[f]" 会更简单;-p

标签: c# xml xpath


【解决方案1】:

Oxygen Editor 是否有可能以不同的方式处理命名空间?我的猜测是 c 元素在命名空间中,但您没有指定一个。

有关示例代码,请参阅 this very similar question - 如果这不是问题,请发布更多详细信息。

编辑:您发布的代码仍然没有使用 XPath 中的命名空间。试试这个:

var manager = new XmlNamespaceManager(WorksheetXml.NameTable);
manager.AddNamespace("n", 
    "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
manager.AddNamespace("r",  
    "http://schemas.openxmlformats.org/officeDocument/2006/relationships");

var nodeList = WorksheetXml.SelectNodes("//n:c[child::n:f]", manager);

(我不知道 cf 元素应该在哪个命名空间中 - 适当调整。)

(请注意,当您没有反斜杠并且字符串在一行上时,无需使用逐字字符串文字。)

【讨论】:

  • c 元素来自默认命名空间。我添加了一个 namespacemgr,但它仍然没有返回任何内容 =/
  • 这里的默认命名空间是什么?我确定您不是指空的名称空间。你是说主要还是关系?查看我的编辑。
  • 我已经在没有 XPath 的情况下解决了这个问题,因为它不起作用,我不得不在上周交付代码。创建这个 'n' - 即使在 xml 中这是“空”命名空间,而 c 只是 ...- 并将 c 处理为 n:c 会有所帮助吗?
  • 是的,因为它实际上不在空命名空间中,而是在该文档级别的默认命名空间中,由祖先的 xmlns="..." 指定属性。
【解决方案2】:

您没有为 XPath 表达式中的节点指定 OpenXML 命名空间。我所知道的所有库存 .NET XPath API 都不会从文档上下文继承任何命名空间 - 因此,如果您没有明确指定它,并且不在 XPath 表达式中使用任何前缀,它就会被视为空命名空间。

假设这是对XmlNode.SelectNode 的调用,您需要第二个参数为XmlNamespaceManager 的2 参数重载。

【讨论】:

  • 我改了调用,把manager作为参数传了,还是不行=/
  • 它不起作用,因为在 XPath 中,不带前缀的元素总是在空命名空间中(即没有 URI),无论您在 XmlNamespaceManager 中做什么。请参阅w3.org/TR/xpath#node-tests:节点测试中的 QName 使用表达式上下文中的命名空间声明扩展为扩展名称。 ...不使用使用 xmlns 声明的默认命名空间:如果 QName 没有前缀,则命名空间 URI 为空(这与扩展属性名称的方式相同)。您必须在 XPath 中使用前缀才能使其工作。
猜你喜欢
  • 2022-01-07
  • 2022-09-28
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-16
相关资源
最近更新 更多