Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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# 使用XPATH在具有命名空间的XML中选择节点时出现问题_C#_.net_Xml_Xpath_Namespaces - Fatal编程技术网

C# 使用XPATH在具有命名空间的XML中选择节点时出现问题

C# 使用XPATH在具有命名空间的XML中选择节点时出现问题,c#,.net,xml,xpath,namespaces,C#,.net,Xml,Xpath,Namespaces,我有以下XPATH行: //数据[@nItem=“1”]/prod/cProd 它使用成功地选择所需的节点,其中它自动标识名称空间,并定义要选择的名称空间 当我使用以下XPATH代码在C#中指定名称空间时: "http://www.portalfiscal.inf.br/nfe//det[@nItem=\"1\"]/prod/cProd" 这给了我一个惊喜: 类型的未处理异常 'System.Xml.XPath.XPathException' 发生在System.Xml.dll中 资料: ““

我有以下XPATH行:

//数据[@nItem=“1”]/prod/cProd

它使用成功地选择所需的节点,其中它自动标识名称空间,并定义要选择的名称空间

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

"http://www.portalfiscal.inf.br/nfe//det[@nItem=\"1\"]/prod/cProd"
这给了我一个惊喜:

类型的未处理异常 'System.Xml.XPath.XPathException' 发生在System.Xml.dll中 资料: ““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>

1.
111

(删除不必要的内容应该不是问题,因为XPath Visualizer为我带来了一个没有任何问题的节点)

因为您既没有向我们展示XML文档,也没有展示您的C代码,我只能猜测您在做什么

好的,看来您正在使用Linq to XML,那么在这里使用以下代码段:

// 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()还有其他问题
除了性能之外。最重要的一点就是它在做什么:忽略名称空间。每当你忽略名称空间时,你都会冒选择节点的风险,这些节点位于不同的名称空间中,但恰好与你要查找的节点具有相同的本地名称。这很糟糕。感谢更新-注意:发布代码和/或XML时,您应该始终在编辑器中高亮显示这些行,然后按下编辑器工具栏上的“代码”按钮(101 010),以对它们进行良好的格式化,并使语法高亮显示等。否则,您的XML将大部分保持隐藏状态。。。。。