2010-01-11 107 views
3

我遇到XPathNavigator问题。我有一个文件,在流中有一堆“主题”元素w/o名称空间。无法让.NET XPathNavigator工作

我使用(表达简单化到最低限度,开始我还以为我的表达是错误的):

XPathDocument xmlDoc = new XPathDocument(stream); 
XPathNavigator xml = xmlDoc.CreateNavigator(); 
XPathNodeIterator iter = xml.Select("//topic"); 

这是行不通的。我可以选择*/*/*或类似的东西,并获得我的“主题”元素。 我试着在线测试仪和其他语言运行我的表达式,他们的工作。

问题:怎么了?我一直怀疑它与被命名的NamespaceManager对象有关,每当我用命名空间解析文档时,这会导致令人难以置信的痛苦,但是这次我所寻找的元素没有明确的命名空间! 我说:

XmlNamespaceManager s = new XmlNamespaceManager(xml.NameTable); 

,并通过作为第二个参数来选择 - 无济于事。我应该如何向这个东西添加“”命名空间/正确使用它?

或者更好的是,有没有办法在.NET中使用XPath,而没有像使用其他语言一样使用该类的可怕憎恶?如果我想命名空间,我可以写他们在表达...

更新: 我想通了,从根节点workaround-复制/粘贴默认的xmlns,然后使用该命名空间:

thisIsRetarded.AddNamespace("x", "urn:xmind:xmap:xmlns:content:2.0"); 
XPathNodeIterator projectIter = projectTree.Select("//x:topic", thisIsRetarded); 

然而,我既不知道默认的URI,也不喜欢用不必要的x:-s来污染我的表达式。所以我现在只需要回答问题的第二部分。

+0

您_are_应该知道的命名空间。如果名称空间不同,则两个具有相同名称的元素是_different_。 – 2010-01-11 01:09:03

+1

我很抱歉地说,命名变量thisIsRetarded对程序员来说只是错误的态度。事情并没有因为你没有理解它们而迟钝。 – Tomalak 2010-01-11 09:14:14

+2

但是,如果元素在xml文档中没有前缀,并且必须在xpath api中创建一些人造构造来选择它,它*就相当愚蠢。 – 2010-10-26 13:17:17

回答

4

我更喜欢使用XmlDocument

XmlDocument doc = new XmlDocument(); 
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); 
nsmgr.AddNamespace("sample", "..."); 
doc.Load(stream); 

XmlNode topic = doc.SelectSingleNode("/sample:topic", nsmgr); 

// If you don't have any namespaces.... 
XmlNode topic2 = doc.SelectSingleNode("/topic"); 
+0

重要的部分是 - 如果你有命名空间,那么你需要在你的XPATH表达式中引用它们! – 2010-01-11 00:43:41

+0

+1我讨厌XPathNavigator对象,除了命名空间 – 2010-02-25 06:07:28