【问题标题】:Parse XML and concatenate divided URL with SimpleXML and XPath解析 XML 并使用 SimpleXML 和 XPath 连接分割的 URL
【发布时间】:2012-03-18 03:33:30
【问题描述】:

我有一个 XML sn-p,它有一个 URL 分段的部分,如下所示。我可以使用 SimpleXML 和 XPath 成功解析它。我的 XPath 查询返回一个包含结果的数组,然后我可以回显它们。没有问题! =)

但是,我想进一步尝试减少代码行并改进我的代码。先看看我的代码:

<?php

$xml_g='
<files>
    <file>
        <filename>itzafile</filename>
        <ext>.tar.gz</ext>
        <url protocol="http://">itzanexample.net/folder/subfolder/</url>
    </file>
    <file>
        <filename>itzavideo</filename>
        <ext>.mp4</ext>
        <url protocol="ftp://">itzanotherurl.com/videos/</url>
    </file>
</files>
';


function URLparts($xml) {
$xmlData= simplexml_load_string("$xml");

$protocol = $xmlData->xpath('//file/url/@protocol');
$url = $xmlData->xpath('//file/url');
$filename = $xmlData->xpath('//file/filename');
$ext = $xmlData->xpath('//file/ext');

echo 'The following it\'s echoed calling 4 different arrays:'."\n\t".$protocol[0], $url[0], $filename[0], $ext[0]."\n\t".$protocol[1], $url[1], $filename[1], $ext[1]."\n\n"; //prints the entire url! Right!


//These variables are arrays, so theoretically it must be possible to create an array of arrays here:
$completeURL = array($protocol,$url,$filename,$ext);
//I've also tried this but it's just the same problem:
//$completeURL = array(array($protocol),array($url),array($filename),array($ext));

echo 'The following should be echoed with a two-dimensional array, but something fails:'."\n\t".$completeURL[0][0][0][0]."\n\n"; //Just prints "http://" WRONG! u.u
/*
 * $completeURL[1][0][0][0] prints the domain+subfolder
 * $completeURL[0][1][0][0] prints ftp://
 * $completeURL[0][0][1][0] prints nothing...
 */

}

URLparts($xml_g);
?>

如您所见,我想避免将 URL 加入为:echo $protocol[0]、$url[0]、$filename[0]、$ext[0],并且我想用更少的代码更简单地完成它变量,如 completeURL[0][0][0][0] (第一个文件节点及其所有相应部分), completeURL[1][1][1][1] (第二个文件节点,所有 url 部分)等等……

但显然我做错了什么。错误在哪里?它应该与我要创建的多维数组有关。

【问题讨论】:

    标签: php xpath multidimensional-array xml-parsing simplexml


    【解决方案1】:

    如果这样做:

    $completeURL = $xmlData->xpath('//file/url/@protocol | //file/url | //file/filename');
    echo $completeURL[2].$completeURL[1].$completeURL[0]."\n";
    echo $completeURL[5].$completeURL[4].$completeURL[3]."\n";
    

    echo 命令打印如下:

    http://itzanexample.net/folder/subfolder/itzafile.tar.gz
    ftp://itzanotherurl.com/videos/itzavideo.mp4
    

    联合运算符的使用 |使用 PHP5 + SimpleXML + XPath 获得预期结果! 但是我不明白为什么必须向后回显结果(2、1、0;5、4、3)而不是 0、1、2、3 等。

    我也不明白为什么下面的表达式给出了相同的结果,以同样的方式回显:

    $completeURL = $xmlData->xpath('//file/filename | //file/url | //file/url/@protocol');
    

    这也解决了这个问题,但我仍然不知道为什么这两个表达式返回相同。所以顺序不重要?为什么需要反向回显??

    所以这确实是一个答案,但需要解释一下。有人知道为什么吗??谢谢! =)

    【讨论】:

    • 显然,echo 输出节点集中每个节点的字符串值,它是 XPath 表达式的评估结果。重要的是要知道,当执行| 时,结果总是按文档顺序显示。所以,| 的参数顺序并不重要。
    • 啊原来如此! “文件顺序”谢谢你帮了我很多=)
    • Metafaniel:我很高兴我能提供帮助。如果是这样,您可以考虑使用更像 SO 的表达方式(+1 或接受)。 :)
    【解决方案2】:

    这可以更简单并且(几乎)完全在 XPath 中完成

       concat(/files/file[$k]/url/@protocol,
              /files/file[$k]/url,
              /files/file[$k]/filename,
              /files/file[$k]/ext
              )
    

    其中$k 必须替换为 1、2、..、count((/files/file)——在这种特殊情况下,只需替换为 1 和 2。

    因此,当计算此 XPath 表达式时

       concat(/files/file[1]/url/@protocol,
              /files/file[1]/url,
              /files/file[1]/filename,
              /files/file[1]/ext
              )
    

    产生想要的正确结果

    http://itzanexample.net/folder/subfolder/itzafile.tar.gz
    

    计算第二个 XPath 表达式时

       concat(/files/file[2]/url/@protocol,
              /files/file[2]/url,
              /files/file[2]/filename,
              /files/file[2]/ext
              )
    

    再次产生所需的正确结果

    ftp://itzanotherurl.com/videos/itzavideo.mp4
    

    【讨论】:

    • 谢谢,这似乎很有用,嗯,但我不确定如何在 PHP5 中执行此操作 =/
    • @Metafaniel:在 C# 中,我会使用 nav.Evaluate(string.Format(theExpression, k));。其中 theExpressionconcat(/files/file[2]/url/@protocol, /files/file[{0}]/url, /files/file[{0}]/filename, /files/file[{0}]/ext ) 。在 C 中可以简单地使用printf()。当然有一种方法可以在 PHP 中做同样的事情。
    • 如果我尝试将 concat 与 XpAth 和 PHP 一起使用,如下所示: '$completeURL = $xmlData->xpath('concat(//file/url/@protocol, //file/url, / /文件/文件名)');'我收到这些错误:PHP Notice: Undefined offset: 0 我找到了另一种方法来做我想做的事,我会在下面发布...
    • @Metafaniel:正如我在之前的评论中所说:当评估结果不是节点集时,请务必找到评估 XPath 表达式的 PHP 方法。
    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    相关资源
    最近更新 更多