Php 在XPATH中使用XHTML文档是否需要名称空间

Php 在XPATH中使用XHTML文档是否需要名称空间,php,html,xhtml,xpath,xml-namespaces,Php,Html,Xhtml,Xpath,Xml Namespaces,我正在为网页的某些特定部分抓取一些网页。我使用php、curl和xpath获取页面的部分。但是人们建议我应该使用XHTML文档的namespaces,以便XPATHs工作。据我所知,名称空间用于避免不同元素名称之间的冲突,那么在这种情况下为什么需要名称空间?实际上,我正在使用Tidy将网页转换为XHTML。我真的需要名称空间吗?如果需要,在哪些情况下,因为没有名称空间的相同代码可以很好地从wikipedia中删除内容。而且,即使修改了php代码以包含名称空间,代码对某些URL也不起作用。您可以看

我正在为网页的某些特定部分抓取一些网页。我使用
php
curl
xpath
获取页面的部分。但是人们建议我应该使用
XHTML
文档的
namespaces
,以便
XPATHs
工作。据我所知,
名称空间
用于避免不同元素名称之间的冲突,那么在这种情况下为什么需要
名称空间
?实际上,我正在使用Tidy将网页转换为XHTML。我真的需要名称空间吗?如果需要,在哪些情况下,因为没有名称空间的相同代码
可以很好地从
wikipedia
中删除内容。而且,即使修改了php代码以包含
名称空间
,代码对某些URL也不起作用。您可以看一下。

首先:名称空间是XML中的一个基本概念。如果您不熟悉名称空间,请花时间学习和理解它们

如果并且仅当正在处理的XML文档使用名称空间时,才需要在XPath表达式中使用名称空间前缀

所有XPath(1.0)名称测试都使用限定名称,即没有名称空间前缀的表达式总是只与没有名称空间的目标匹配。这意味着表达式
/element-1/element-2
总是在搜索没有命名空间定义的元素(换句话说,它们不属于任何命名空间,换句话说,它们有空的命名空间URI)。示例XPath表达式适用于此文档

<element-1>
    <element-2>Works!</element-2>
</element-1>
<ns:element-1 xmlns:ns="http://example.com">
    <ns:element-2>Doesn't work</ns:element-2>
</ns:element-1>
<element-1 xmlns="http://example.com">
    <element-2>Similar to previous, and doesn't work either.</element-2>
</element-1>
…与第二个文档示例相同,在其上使用XPath还需要使用名称空间前缀

从该文档中搜索数据需要使用一些前缀注册名称空间URI,然后在XPath表达式中使用该前缀。类似于
/px:element-1/px:element-2
。请注意,您注册的前缀不需要与文档中使用的前缀匹配,但URI必须完全匹配。需要注意的另一点是,即使默认名称空间中的元素没有前缀,您仍然需要使用XPath表达式中定义的前缀来匹配它们

因此,XPath查询中是否需要名称空间前缀取决于文档。一些网站将其页面作为有效的XHTML文档,因此所有元素都属于XHTML名称空间。其他一些站点提供的HTML或XHTML没有名称空间,这在技术上是无效的XHTML

名称空间前缀的注册方式取决于您使用的XML框架或库。在php和SimpleXML中,这大致是这样做的

$your_xml_doc->registerXPathNamespace("ns", "http://example.com");
$result = $your_xml_doc->xpath('/ns:element-1/ns:element-2');

首先:名称空间是XML中的一个基本概念。如果您不熟悉名称空间,请花时间学习和理解它们

如果并且仅当正在处理的XML文档使用名称空间时,才需要在XPath表达式中使用名称空间前缀

所有XPath(1.0)名称测试都使用限定名称,即没有名称空间前缀的表达式总是只与没有名称空间的目标匹配。这意味着表达式
/element-1/element-2
总是在搜索没有命名空间定义的元素(换句话说,它们不属于任何命名空间,换句话说,它们有空的命名空间URI)。示例XPath表达式适用于此文档

<element-1>
    <element-2>Works!</element-2>
</element-1>
<ns:element-1 xmlns:ns="http://example.com">
    <ns:element-2>Doesn't work</ns:element-2>
</ns:element-1>
<element-1 xmlns="http://example.com">
    <element-2>Similar to previous, and doesn't work either.</element-2>
</element-1>
…与第二个文档示例相同,在其上使用XPath还需要使用名称空间前缀

从该文档中搜索数据需要使用一些前缀注册名称空间URI,然后在XPath表达式中使用该前缀。类似于
/px:element-1/px:element-2
。请注意,您注册的前缀不需要与文档中使用的前缀匹配,但URI必须完全匹配。需要注意的另一点是,即使默认名称空间中的元素没有前缀,您仍然需要使用XPath表达式中定义的前缀来匹配它们

因此,XPath查询中是否需要名称空间前缀取决于文档。一些网站将其页面作为有效的XHTML文档,因此所有元素都属于XHTML名称空间。其他一些站点提供的HTML或XHTML没有名称空间,这在技术上是无效的XHTML

名称空间前缀的注册方式取决于您使用的XML框架或库。在php和SimpleXML中,这大致是这样做的

$your_xml_doc->registerXPathNamespace("ns", "http://example.com");
$result = $your_xml_doc->xpath('/ns:element-1/ns:element-2');
可以使用不使用名称空间的XPath表达式

如果您正在抓取web内容,并且不确定它是XHTML还是未绑定到命名空间的格式良好的HTML,那么您可能会发现为XPath使用更通用的匹配条件更方便,因为它会忽略元素的命名空间

您可以通过对任何元素(例如
*
)进行泛型匹配,然后对元素的
local-name()
使用谓词过滤器(例如
*[local-name()='table']

这样做将匹配具有该名称的任何元素,无论它是否绑定到特定命名空间

例如:

//*[local-name()='body']/*[local-name()='table'][4]
     /*[local-name()='tbody']/*[local-name()='tr'][3]
     /*[local-name()='td'][4]
可以使用不使用名称空间的XPath表达式

如果您正在抓取web内容,并且不确定它是XHTML还是未绑定到命名空间的格式良好的HTML,那么您可能会发现为XPath使用更通用的匹配条件更方便,因为它会忽略元素的命名空间

您可以通过对任何元素(例如
*
)进行泛型匹配,然后对元素的
local-name()
使用谓词过滤器(例如
*[local-name()='table']

这样做将匹配具有该名称的任何元素,而