我有一个应用程序,必须根据XPath加载XML文档和输出节点.
假设我从这样的文档开始:
<aaa>
...[many nodes here]...
<bbb>text</bbb>
...[many nodes here]...
<bbb>text</bbb>
...[many nodes here]...
</aaa>
Run Code Online (Sandbox Code Playgroud)
用XPath //bbb
到目前为止一切都很好.
并且选择doc.SelectNodes("//bbb");返回所需节点的列表.
然后有人<myfancynamespace:foo/>在根标签中上传一个节点和一个额外名称空间的文档,一切都中断了.
为什么?//bbb并没有给出一点该死的myfancynamespace,理论上它应该是好的//myfancynamespace:foo,因为没有歧义,但表达式返回0结果,就是这样.
这种行为有解决方法吗?
我确实有一个文档的命名空间管理器,我将它传递给Xpath查询.但我不知道名称空间和前缀,所以我不能在查询之前添加它们.
在进行任何选择之前,是否必须预先解析文档以填充命名空间管理器?为什么在地球上这样的行为,它只是没有意义.
编辑:
我正在使用:
XmlDocument和XmlNamespaceManager
EDIT2:
XmlDocument doc = new XmlDocument();
doc.XmlResolver = null;
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
//I wish I could:
//nsmgr.AddNamespace("magic", "http://magicnamespaceuri/
//...
doc.LoadXML(usersuppliedxml);
XmlNodeList nodes = doc.SelectNodes(usersuppliedxpath, nsmgr);//usersuppliedxpath -> "//bbb"
//nodes.Count should be > 0, but with namespaced document they are 0
Run Code Online (Sandbox Code Playgroud)
EDIT3: 找到一篇文章,用一种解决方法描述问题的实际情况,但不是很漂亮的解决方法:http://codeclimber.net.nz/archive/2008/01/09/How-to-query-a-XPath -doc -即,具有-A-的Default.aspx
几乎似乎剥离xmlns是要走的路......
har*_*rpo 13
您错过了XML命名空间的全部内容.
但是,如果您确实需要对将使用未知命名空间的文档执行XPath,并且您真的不关心它,则需要将其删除并重新加载文档.除非您想local-name()在选择器中的每个点使用该函数,否则XPath将无法以与命名空间无关的方式工作.
private XmlDocument StripNamespace(XmlDocument doc)
{
if (doc.DocumentElement.NamespaceURI.Length > 0)
{
doc.DocumentElement.SetAttribute("xmlns", "");
// must serialize and reload for this to take effect
XmlDocument newDoc = new XmlDocument();
newDoc.LoadXml(doc.OuterXml);
return newDoc;
}
else
{
return doc;
}
}
Run Code Online (Sandbox Code Playgroud)
<myfancynamespace:foo/>不一定是一样的<foo/>.
命名空间很重要. 但是我可以理解你的挫败感,因为它们通常会打破代码,因为各种实现(C#,Java,...)倾向于以不同的方式输出它.
我建议您更改XPath以允许接受所有名称空间.例如,而不是
//bbb
Run Code Online (Sandbox Code Playgroud)
将其定义为
//*[local-name()='bbb']
Run Code Online (Sandbox Code Playgroud)
那应该照顾它.
| 归档时间: |
|
| 查看次数: |
10388 次 |
| 最近记录: |