我有以下 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:Field
那么还有另一种方法:
/*[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/']
或者您可以在库中注册名称空间,然后显式指定该名称空间的前缀并将其添加到 xpath 表达式,其方法取决于您使用的库。
您很可能必须使用您的 xpath 库注册该名称空间 uri。根据库的不同,您可能能够使用“默认”前缀,或者您可能需要给它一个命名前缀并在您的 xpath 查询中使用它。
例如,在使用 DOMXPath 的 php(因为您没有指定语言)中,您可以执行以下操作:
$xpath = new DOMXPath($document);
$xpath->registerNamespace('x', 'http://schemas.microsoft.com/sharepoint/soap/');
$xpath->query('/x:List/x:Fields/x:Field');
x:
部分)
<foo:List xmlns:foo="http://schemas.microsoft.com/sharepoint/soap/"><foo:Fields><foo:Field></foo:Field></foo:Fields></foo:List>
我在使用 Xalan-c 时遇到了这个问题
我最初不太明白的一点是,XPath 或 XSLT 命名空间别名/前缀可能与文档的不同 - 取决于您的命名空间解析器。
似乎如果文档上有名称空间,那么除非使用名称空间,否则它无法匹配路径元素。 (标准但并不总是遵循?)
XalanDocumentPrefixResolver 会将 XPath 或 XSLT 命名空间映射到 URI,并尝试通过获取前缀来给它们 id - 如果没有前缀,它使用的名称变成了 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
只要您在任何其他节点下方没有“字段”并且只要子节点没有命名空间,这就会起作用。
不定期副业成功案例分享
@*[name() = 'myName']
或@*[name() = 'myPrefix:myName']
/*[local-name()="mynode" and @myAttr="value"]
一样使用它?