【问题标题】:Problems in selecting a node in XML with Namespace using XPATH使用 XPATH 在带有 Namespace 的 XML 中选择节点时出现问题
【发布时间】:2011-02-06 03:27:57
【问题描述】:

我有以下 XPATH 行:

//det[@nItem="1"]/prod/cProd

使用XPath Visualizer 成功选择所需的节点,它会自动识别命名空间,并定义要选择的命名空间。

当我在 C# 中使用以下 XPATH 代码指定命名空间时:

"http://www.portalfiscal.inf.br/nfe//det[@nItem=\"1\"]/prod/cProd"

它给了我一个 XPathException:

未处理的类型异常 'System.Xml.XPath.XPathException' 发生在 System.Xml.dll 附加 信息: 'http://www.portalfiscal.inf.br/nfe//det[@nItem="1"]/prod/cProd' 具有无效的限定名称。

(如您所见,它不是任何转义字符或任何东西,因为它为我提供了我在异常中试图达到的内容)

如果我知道 XPath 的命名空间,如何正确选择此节点?

--[编辑]-- 我尝试读取节点的完整行:

doc.XPathSelectElement("http://www.portalfiscal.inf.br/nfe//det[@nItem=\"1\"]/prod/cProd").Value;

还有去掉不必要的东西的XML:

<?xml version="1.0" encoding="utf-8"?>
<enviNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.10">
<idLote>1</idLote>
<NFe>
<infNFe versao="1.10" Id="NFe31100118583682000178550010000077778397333128">
<det nItem="1">
<prod>
<cProd>111</cProd>
</prod>
</det>
</infNFe>
</NFe>
</enviNFe>

(剪掉不必要的东西应该不是问题,因为 XPath Visualizer 给我带来了完全没有问题的节点)

【问题讨论】:

  • 感谢您的更新 - 注意:发布代码和/或 XML 时,您应该始终在编辑器中突出显示这些行,然后按“代码”按钮(101 010)在编辑器工具栏上很好地格式化它们并获得语法突出显示等。否则,您的 XML 将大部分保持隐藏.....

标签: c# .net xml xpath namespaces


【解决方案1】:

由于您既没有向我们展示 XML 文档,也没有展示您拥有的 C# 代码,我只能猜测您在做什么......

好的,看来您使用的是 Linq-to-XML,所以在此处使用此代码 sn-p:

// Create and load XML reader
XmlReader reader = XmlReader.Create(new FileStream(@"D.\test.xml", FileAccess.Read));

// get the root element    
XElement root = XElement.Load(reader);


// create instance of XML namespace manager
XmlNamespaceManager nsmgr = new XmlNamespaceManager(reader.NameTable);

// add your namespace to the manager and give it a prefix
nsmgr.AddNamespace("ns", "http://www.portalfiscal.inf.br/nfe");

XElement node = root.XPathSelectElement("//ns:det[@nItem="1"]/ns:prod/ns:cProd", nsmgr);
.......

类似的东西。您基本上必须创建某种 XML 命名空间,给它一个前缀,然后在您的 XPath 表达式中使用该前缀 - 而不是整个命名空间 - 只是前缀。

【讨论】:

  • 如果您不担心性能,您可以通过忽略命名空间 "//*[local-name()='det' 和 @*[local-name()='nItem' 来选择节点。 ]=1]/*[local-name()='prod']/*[local-name()='cProd']"
  • 我已经看到在 xpath 的开头使用了命名空间(就像我的非工作示例)有没有办法把它放在 xpath 语法中?
  • @MarceloRamires:据我所知,不——据我所知,您必须为 XML 命名空间创建一个前缀并以这种方式使用它。我从未见过直接在 XPath 中使用的完整命名空间
  • 使用local-name()除了性能还有其他问题。最重要的是它正在做的事情:忽略命名空间。每当您忽略命名空间时,您都会冒着选择位于不同命名空间中但恰好与您要查找的名称相同的本地名称的节点的风险。这很糟糕。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
  • 2012-02-14
  • 1970-01-01
相关资源
最近更新 更多