Xml命名空间打破我的xpath!

我有以下XML:

<List xmlns="http://schemas.microsoft.com/sharepoint/soap/"> <Fields> <Field> </Field> </Fields> </List> 

这是从SharePoint Web服务返回的XML精简版本。 我也有以下xPath:

 /List/Fields/Field 

当我从我的XML中删除xmlns的xPath工作正常。 当它在我的xPath找不到任何东西。 有什么我应该做不同的我的xPath? 修改XML不是一个选项。

我也有以下xPath:

 /List/Fields/Field 

当我从我的XML中删除xmlns的xPath工作正常。 当它在我的xPath找不到任何东西

如果你不能注册一个名字空间绑定,并且不能使用 (假设注册的前缀是“x”):

 /x:List/x:Fields/x:Fiels 

那么还有另一种方式

 /*[name()='List']/*[name()='Fields']/*[name()='Field'] 

List元素已经被定义为一个默认的名字空间,这被所有元素所采用。

因此,您需要忽略元素名称空间,如下所示:

 /*[local-name()='List']/*[local-name()='Fields]/*[local-name()='Field] 

但这意味着xpath将使用List – Fields – Field来获取其他任何元素

您可以执行命名空间检查以及本地名称检查,如下所示:

 /*[local-name()='List' and namespace-uri()='http://schemas.microsoft.com/sharepoint/soap/']/*[local-name()='Fields' and namespace-uri()='http://schemas.microsoft.com/sharepoint/soap/']/*[local-name()='Field' and namespace-uri()='http://schemas.microsoft.com/sharepoint/soap/'] 

或者,您可以在库中注册名称空间,然后明确指定该名称空间的前缀,并将其添加到xpathexpression式中,该expression式的方法取决于您正在使用的库。

你很可能必须注册该命名空间uri与你的xpath库。 根据库,你可以使用“默认”前缀,或者你可能需要给它一个命名前缀,并在你的xpath查询中使用它。

例如,在PHP(因为你没有指定一种语言)使用DOMXPath你可以做这样的事情:

 $xpath = new DOMXPath($document); $xpath->registerNamespace('x', 'http://schemas.microsoft.com/sharepoint/soap/'); $xpath->query('/x:List/x:Fields/x:Field'); 

我在使用Xalan-c时遇到了这个问题

我最初不太明白的一点是,XPath或XSLT命名空间别名/前缀可能与文档的别名不同 – 取决于您的命名空间parsing器。

看起来,如果文档上有一个命名空间,那么它将无法匹配path元素,除非使用了命名空间。 (标准但不总是跟着?)

XalanDocumentPrefixResolver会将XPath或XSLT命名空间映射到URI,并尝试通过获取前缀来为它们提供id – 在没有前缀的情况下,它使用的名称转换为xmlns

/xmlns:List/xmlns:Fields/xmlns:Field

或者,你可以创build自己的parsing器,但它仍然需要在xpath中使用最小的命名空间:(

这里有一个我在testing时一起入侵,无法保证内存

 // don't care what prefix given, there can only be the one struct NoPrefixResolver : public xalanc::PrefixResolver { NoPrefixResolver(const xalanc::XalanDOMString& theURI) : m_uri(theURI){} virtual const xalanc::XalanDOMString* getNamespaceForPrefix(const xalanc::XalanDOMString& prefix) const { return &m_uri; } virtual const xalanc::XalanDOMString& getURI() const { return m_uri; } const xalanc::XalanDOMString m_uri; }; /x:List/x:Fields/x:Field /a:List/b:Fields/c:Field 

如果您可以跳过文档元素,则以下XPath也可以帮助您:

 //Fields/Field 

只要没有任何其他节点下面的“字段”,并且只要子节点没有名称空间,就可以工作。