Xml命名空间打破我的xpath!
我有以下XML:Xml命名空间打破我的xpath!
<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']
您很可能必须在您的xpath库中注册该命名空间uri。根据库的不同,您可能可以使用“默认”前缀,或者您可能需要为其指定一个名称前缀,并在xpath查询中使用它。
例如,在PHP(因为你没有指定语言)使用DOMXPath你可以做这样的事情:
$xpath = new DOMXPath($document);
$xpath->registerNamespace('x', 'http://schemas.microsoft.com/sharepoint/soap/');
$xpath->query('/x:List/x:Fields/x:Field');
是啊,我是一个.NET人,通常我的解决方案就是.NET的等价物。不幸的是,我们正在使用第三方的“快速”开发环境,它不会使我们有能力做到这一点...... – 2011-03-09 00:03:00
另外,如果没有前缀,他们为什么还要包含一个名称空间? (xPath的'x:'部分) – 2011-03-09 00:03:44
有一个名称空间。它只是在这个特定的文件中使用'默认'前缀。该文件将是相同的语义是吧'
列表元素已经定义了默认的命名空间,这是由采用里面的所有元素。
你因此需要忽略,像这样的元素命名空间:
/*[local-name()='List']/*[local-name()='Fields]/*[local-name()='Field]
但这意味着与XPath将拿起任何其他元素与列表 - 田 - 现场
你可以做一个命名空间检查以及像这样的本地名称检查:
/*[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/']
或者您可以向库注册命名空间,然后明确指定该命名空间和广告的前缀将其转换为xpath表达式,其方法依赖于您正在使用的库。
这个答案正在工作,而接受的答案不工作....谢谢@ zode64这个帮助。我疯狂地让我的xpath表达式为包含xml的名称空间工作。现在,我不需要担心名称空间了。万分感谢.. – 2016-02-09 13:43:45
我刚刚一直有这个问题,而使用的Xalan-C
我最初不太明白的一点是,XPath或XSLT命名空间别名/前缀可能与文档不同 - 取决于您的命名空间解析器。
看起来,如果文档上有一个命名空间,那么它将无法匹配路径元素,除非使用了命名空间。 (标准但并不总是遵循?)
的XalanDocumentPrefixResolver将XPath或XSLT命名空间映射到URI和尝试,并通过获取前缀给它们编号 - 这里没有前缀它使用它变成的xmlns
/xmlns:List/xmlns:Fields/xmlns:Field
或者你的名字可以创建自己的解析器,但它仍然需要在XPath :(
这里使用的最小的命名空间是一个我砍死在一起,同时测试,无记忆保证
// 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
这个工作,只要你没有“字段”下的任何其他节点和大的子节点有没有名字空间。
许多重复之一:http://*.com/questions/11345/xpaths-and-default-namespaces – 2011-03-09 19:45:28
没有,这不是重复。这个问题特别指出了C#,而这是严格的xpath/xml。而且,他的命名空间不是空白的,而我的是。 – 2011-03-21 14:37:51
您需要某种程度的抽象......您在问如何使用XPath表达式在默认名称空间下选择元素。 **这是最常见的**。 – 2011-03-21 16:09:36