Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中使用xhtml:link解析XML?_Php_Xml_Parsing_Xhtml_Hreflang - Fatal编程技术网

如何在PHP中使用xhtml:link解析XML?

如何在PHP中使用xhtml:link解析XML?,php,xml,parsing,xhtml,hreflang,Php,Xml,Parsing,Xhtml,Hreflang,目标是: 导入外部XML文件(在本例中,它是内联的) 获取,保存到变量中 找到具有href lang=“fr ca”属性的,获取href值,保存到变量中 在数据库中插入这两个选项 我的问题是:我甚至无法让PHP识别xhtml:link是项的子节点;即使我只是简单地为吐出nodeValue,它也会忽略所有子节点 我正在使用/尝试的代码: <?php $xml = <<< XML <?xml version="1.0" encoding="UTF-8"?> &

目标是:

  • 导入外部XML文件(在本例中,它是内联的)
  • 获取,保存到变量中
  • 找到具有href lang=“fr ca”属性的,获取href值,保存到变量中
  • 在数据库中插入这两个选项
我的问题是:我甚至无法让PHP识别xhtml:link是项的子节点;即使我只是简单地为吐出nodeValue,它也会忽略所有子节点

我正在使用/尝试的代码:

<?php
$xml = <<< XML
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <loc>https://www.example.com/ca/en/cat/categories/series/07660/</loc>
  <lastmod>2018-11-07</lastmod>
  <changefreq>daily</changefreq>
  <priority>1.0</priority>
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="en-ae" href="https://www.example.com/ae/en/cat/categories/series/07660/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="de-at" href="https://www.example.com/at/de/cat/07660/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="en-au" href="https://www.example.com/au/en/cat/categories/series/07660/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="en-ca" href="https://www.example.com/ca/en/cat/categories/series/07660/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="fr-ca" href="https://www.example.com/ca/fr/cat/categories/series/07660/" />
</url>
<url xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <loc>https://www.example.com/ca/en/cat/categories/series/07683/</loc>
  <lastmod>2018-11-07</lastmod>
  <changefreq>daily</changefreq>
  <priority>1.0</priority>
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="en-ae" href="https://www.example.com/ae/en/cat/categories/series/07683/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="de-at" href="https://www.example.com/at/de/cat/07683/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="en-au" href="https://www.example.com/au/en/cat/categories/series/07683/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="fr-be" href="https://www.example.com/be/fr/collections/07683/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="nl-be" href="https://www.example.com/be/nl/collecties/07683/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="en-bh" href="https://www.example.com/bh/en/cat/07683/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="en-ca" href="https://www.example.com/ca/en/cat/categories/series/07683/" />
  <xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="alternate" hreflang="fr-ca" href="https://www.example.com/ca/fr/cat/categories/series/07683/" />
</url>
</urlset>
XML;

$urlsxml = new DOMDocument;
$urlsxml->loadXML($xml);
$urls = $urlsxml->getElementsByTagName('url');

for ($i = 0; $i < $urls->length; $i++) {

      echo $urls->item($i)->nodeValue;
      echo $urls->getElementsByTagName("xhtml:link")->attributes->getNamedItem("hreflang")->nodeValue;

      // INSERT INTO DB

}

?>

https://www.example.com/ca/en/cat/categories/series/07660/
2018-11-07
每日的
1
https://www.example.com/ca/en/cat/categories/series/07683/
2018-11-07
每日的
1
XML;
$urlsxml=新文档;
$urlsxml->loadXML($xml);
$url=$urlsxml->getElementsByTagName('url');
对于($i=0;$i<$url->length;$i++){
echo$url->item($i)->nodeValue;
echo$url->getElementsByTagName(“xhtml:link”)->attributes->getNamedItem(“hreflang”)->nodeValue;
//插入数据库
}
?>

没有想法;任何帮助都将不胜感激。

在数据库中插入的实际操作超出了此处代码的范围,但要解析XML,您可以做如下简单的事情(基于本地保存的XML副本,而不是使用
herdoc
语法)~文件名仅用于识别

起初,我认为这需要注册
名称空间
,并在XPath表达式中使用,但事实并非如此-对每个
url
节点进行简单的XPath查询就足够了~使用父节点
url
作为查询的引用节点

$file='so-stack-xml-namespace.xml';


libxml_use_internal_errors( true );
$dom=new DOMDocument;
$dom->validateOnParse=true;
$dom->recover=true;
$dom->strictErrorChecking=true;
$dom->load( $file );
libxml_clear_errors();

$xp=new DOMXPath( $dom );

$urls=$dom->getElementsByTagName('url');
foreach( $urls as $url ){
    $href=$url->nodeValue;
    $frca=$xp->query('xhtml:link[@hreflang="fr-ca"]',$url)->item(0)->getAttribute('href');
    /* do something with the variables...add to DB */
    printf('href:%s<br />frca:%s<br /><br />', $href,$frca);
}
$file='so-stack-xml-namespace.xml';
libxml\u使用\u内部错误(true);
$dom=新的DOMDocument;
$dom->validateOnParse=true;
$dom->recover=true;
$dom->strigerrorchecking=true;
$dom->load($file);
libxml_clear_errors();
$xp=新的DOMXPath($dom);
$url=$dom->getElementsByTagName('url');
foreach($url作为$url){
$href=$url->nodeValue;
$frca=$xp->query('xhtml:link[@hreflang=“fr-ca”]”,$url)->item(0)->getAttribute('href');
/*对变量执行一些操作…添加到DB*/
printf('href:%s
frca:%s

',$href,$frca); }
在数据库中插入的实际操作超出了此处代码的范围,但要解析XML,您可以做如下简单的事情(基于本地保存的XML副本,而不是使用
herdoc
语法)~文件名仅用于识别

起初,我认为这需要注册
名称空间
,并在XPath表达式中使用,但事实并非如此-对每个
url
节点进行简单的XPath查询就足够了~使用父节点
url
作为查询的引用节点

$file='so-stack-xml-namespace.xml';


libxml_use_internal_errors( true );
$dom=new DOMDocument;
$dom->validateOnParse=true;
$dom->recover=true;
$dom->strictErrorChecking=true;
$dom->load( $file );
libxml_clear_errors();

$xp=new DOMXPath( $dom );

$urls=$dom->getElementsByTagName('url');
foreach( $urls as $url ){
    $href=$url->nodeValue;
    $frca=$xp->query('xhtml:link[@hreflang="fr-ca"]',$url)->item(0)->getAttribute('href');
    /* do something with the variables...add to DB */
    printf('href:%s<br />frca:%s<br /><br />', $href,$frca);
}
$file='so-stack-xml-namespace.xml';
libxml\u使用\u内部错误(true);
$dom=新的DOMDocument;
$dom->validateOnParse=true;
$dom->recover=true;
$dom->strigerrorchecking=true;
$dom->load($file);
libxml_clear_errors();
$xp=新的DOMXPath($dom);
$url=$dom->getElementsByTagName('url');
foreach($url作为$url){
$href=$url->nodeValue;
$frca=$xp->query('xhtml:link[@hreflang=“fr-ca”]”,$url)->item(0)->getAttribute('href');
/*对变量执行一些操作…添加到DB*/
printf('href:%s
frca:%s

',$href,$frca); }
如果将XML文件放入变量中,则可以使用循环提取值:

$xml = file_get_contents("your_xml_file");
$tags = explode("<", $xml);
$loc = "not found";
$frhref = "not found";

foreach ($tags as $tag){
    if(strpos($tag, "loc>") === 0){
        $loc = substr($tag, 4);
    }
    if(strpos($tag, "xhtml:link") === 0){
        $at = strpos($tag, "hreflang") + 9;
        $lang = substr($tag, $at, 7);
        if($lang == '"fr-ca"'){
            $at = strpos($tag, "href=") + 6;
            $_href = substr($tag, $at);
            $until = strpos($_href, '"');
            $frhref = substr($_href, 0, $until);
        }
    }
}
echo $loc, " ", $frhref; //put them in your db
$xml=file\u get\u contents(“您的xml\u文件”);
$tags=explode(“”===0){
$loc=substr($tag,4);
}
if(strpos($tag,“xhtml:link”)==0){
$at=strpos($tag,“hreflang”)+9;
$lang=substr($tag,$at,7);
如果($lang='“fr ca”')){
$at=strpos($tag,“href=”)+6;
$\u href=substr($tag,$at);
$until=strpos($_href,“”);
$frref=substr($\u href,0,$until);
}
}
}
echo$loc,“,$frref;//将它们放入数据库中

我用您的内容对其进行了测试:

如果将XML文件放入变量中,则可以使用循环提取值:

$xml = file_get_contents("your_xml_file");
$tags = explode("<", $xml);
$loc = "not found";
$frhref = "not found";

foreach ($tags as $tag){
    if(strpos($tag, "loc>") === 0){
        $loc = substr($tag, 4);
    }
    if(strpos($tag, "xhtml:link") === 0){
        $at = strpos($tag, "hreflang") + 9;
        $lang = substr($tag, $at, 7);
        if($lang == '"fr-ca"'){
            $at = strpos($tag, "href=") + 6;
            $_href = substr($tag, $at);
            $until = strpos($_href, '"');
            $frhref = substr($_href, 0, $until);
        }
    }
}
echo $loc, " ", $frhref; //put them in your db
$xml=file\u get\u contents(“您的xml\u文件”);
$tags=explode(“”===0){
$loc=substr($tag,4);
}
if(strpos($tag,“xhtml:link”)==0){
$at=strpos($tag,“hreflang”)+9;
$lang=substr($tag,$at,7);
如果($lang='“fr ca”')){
$at=strpos($tag,“href=”)+6;
$\u href=substr($tag,$at);
$until=strpos($_href,“”);
$frref=substr($\u href,0,$until);
}
}
}
echo$loc,“,$frref//把它们放在你的数据库里

我用您的内容测试了它:

XML使用两个名称空间
http://www.sitemaps.org/schemas/sitemap/0.9
无别名且
http://www.w3.org/1999/xhtml
别名为
xhtml
。要使用名称空间读取XML,应该使用DOM方法的
*NS
变体

$urls = $urlsxml->getElementsByTagNameNS(
  'http://www.sitemaps.org/schemas/sitemap/0.9', 'url'
);

$urls[$i]->getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'link');
第一个参数是名称空间URI,第二个参数是本地名称(带前缀的节点名称)。在本例中,最好为名称空间URI使用常量/变量

更合适的选择是Xpath。它允许您使用位置路径和条件来获取节点

$document = new DOMDocument;
$document->loadXML($xml);
// create an xpath instance for the document
$xpath = new DOMXpath($document);
// register the namespaces for your own prefixes
$xpath->registerNameSpace('s', 'http://www.sitemaps.org/schemas/sitemap/0.9');
$xpath->registerNameSpace('x', 'http://www.w3.org/1999/xhtml');

// iterate all sitemap url elements
foreach ($xpath->evaluate('//s:url') as $url) {
  $data = [
    // get the sitemap loc child element as a string
    'loc' => $xpath->evaluate('string(s:loc)', $url),
    // get the href attribute of the xhtml link element (with language condition)
    'fr-ca' => $xpath->evaluate('string(x:link[@hreflang="fr-ca"]/@href)', $url),
  ];
  var_dump($data);
}
输出:

array(2) { 
  ["loc"]=> 
  string(58) "https://www.example.com/ca/en/cat/categories/series/07660/" 
  ["fr-ca"]=> 
  string(58) "https://www.example.com/ca/fr/cat/categories/series/07660/" 
} 
array(2) { 
  ["loc"]=> 
  string(58) "https://www.example.com/ca/en/cat/categories/series/07683/" 
  ["fr-ca"]=> 
  string(58) "https://www.example.com/ca/fr/cat/categories/series/07683/" 
}

Xpath中的
string()
将列表中的第一个节点强制转换为字符串。它允许您避免显式访问节点对象属性。例如
$xpath->evaluate('s:loc',$url)->item(0)->textContent可以写成
$xpath->evaluate('string(s:loc)',$url)。与属性访问不同,如果不存在匹配的节点,Xpath强制转换将不会因错误而失败。它将返回一个空字符串

XML使用两个名称空间
http://www.sitemaps.org/schemas/sitemap/0.9
无别名且
http://www.w3.org/1999/xhtml
别名为
xhtml
。读取XML