1

我已经在这方面搜索了一段时间,但运气不佳。我找到了很多资源来展示如何从动态 XML 中回显数据,但我是 PHP 新手,我写的任何东西似乎都无法准确地抓取和打印我想要的东西,尽管从我所听到的一切来看,它应该相对容易。源 XML(位于 192.168.0.15:8080/requests/status.xml)如下:

<root>
  <fullscreen>0</fullscreen>
  <volume>97</volume>
  <repeat>false</repeat>
  <version>2.0.5 Twoflower</version>
  <random>true</random>
  <audiodelay>0</audiodelay>
  <apiversion>3</apiversion>
  <videoeffects>
  <hue>0</hue>
  <saturation>1</saturation>
  <contrast>1</contrast>
  <brightness>1</brightness>
  <gamma>1</gamma>
  </videoeffects>
  <state>playing</state>
  <loop>true</loop>
  <time>37</time>
  <position>0.22050105035305</position>
  <rate>1</rate>
  <length>168</length>
  <subtitledelay>0</subtitledelay>
  <equalizer/>
  <information>
  <category name="meta">
  <info name="description">
  000003EC 00000253 00000D98 000007C0 00009C57 00004E37 000068EB 00003DC5 00015F90 00011187
  </info>
  <info name="date">2003</info>
  <info name="artwork_url"> file://brentonshp04/music%24/Music/Hackett%2C%20Steve/Guitar%20Noir%20%26%20There%20Are%20Many%20Sides%20to%20the%20Night%20Disc%202/Folder.jpg
  </info>
  <info name="artist">Steve Hackett</info>
  <info name="publisher">Recall</info>
  <info name="album">Guitar Noir &amp; There Are Many Sides to the Night Disc 2
  </info>
  <info name="track_number">5</info>
  <info name="title">Beja Flor [Live]</info>
  <info name="genre">Rock</info>
  <info name="filename">Beja Flor [Live]</info>
  </category>
  <category name="Stream 0">
  <info name="Bitrate">128 kb/s</info>
  <info name="Type">Audio</info>
  <info name="Channels">Stereo</info>
  <info name="Sample rate">44100 Hz</info>
  <info name="Codec">MPEG Audio layer 1/2/3 (mpga)</info>
  </category>
  </information>
  <stats>
  <lostabuffers>0</lostabuffers>
  <readpackets>568</readpackets>
  <lostpictures>0</lostpictures>
  <demuxreadbytes>580544</demuxreadbytes>
  <demuxbitrate>0.015997290611267</demuxbitrate>
  <playedabuffers>0</playedabuffers>
  <demuxcorrupted>0</demuxcorrupted>
  <sendbitrate>0</sendbitrate>
  <sentbytes>0</sentbytes>
  <displayedpictures>0</displayedpictures>
  <demuxreadpackets>0</demuxreadpackets>
  <sentpackets>0</sentpackets>
  <inputbitrate>0.016695899888873</inputbitrate>
  <demuxdiscontinuity>0</demuxdiscontinuity>
  <averagedemuxbitrate>0</averagedemuxbitrate>
  <decodedvideo>0</decodedvideo>
  <averageinputbitrate>0</averageinputbitrate>
  <readbytes>581844</readbytes>
  <decodedaudio>0</decodedaudio>
  </stats>
  </root> 

我正在尝试编写的是一个简单的 PHP 脚本,它与艺术家的名字相呼应(在本例中为 Steve Hackett)。实际上,我希望它与艺术家、歌曲和专辑相呼应,但我有信心,如果有人向我展示如何检索其中的一个,我可以自己解决剩下的问题。

我的脚本中实际上似乎有效的一小部分如下所示。我已经尝试了比下面更多的东西,但是我忽略了我所知道的事实是行不通的。

<?PHP
$file = file_get_contents('http://192.168.0.15:8080/requests/status.xml');
$sxe = new SimpleXMLElement($file);

foreach($sxe->...

echo "Artist: "...

?>

我想我需要使用foreachand echo,但我不知道如何以打印这些信息括号之间的内容的方式进行操作。

如果我遗漏了什么,我很抱歉。我不仅是 PHP 新手,而且也是 StackOverflow 的新手。我在其他项目中引用了这个网站,它总是非常有帮助,所以提前感谢您的耐心和帮助!

////////完成的工作脚本 - 感谢 Stefano 和所有帮助过的人!

<?PHP
$file = file_get_contents('http://192.168.0.15:8080/requests/status.xml');
$sxe = new SimpleXMLElement($file);

$artist_xpath = $sxe->xpath('//info[@name="artist"]');
$album_xpath = $sxe->xpath('//info[@name="album"]');
$title_xpath = $sxe->xpath('//info[@name="title"]');


$artist = (string) $artist_xpath[0];
$album = (string) $album_xpath[0];
$title = (string) $title_xpath[0];


echo "<B>Artist: </B>".$artist."</br>";
echo "<B>Title: </B>".$title."</br>";
echo "<B>Album: </B>".$album."</br>";
?>
4

2 回答 2

2

您可以使用XPath获得相同的结果,而不是使用for循环:

// Extraction splitted across two lines for clarity
$artist_xpath = $sxe->xpath('//info[@name="artist"]');
$artist = (string) $artist_xpath[0];
echo $artist;

您将不得不调整 xpath 表达式(即@name=...适当更改),但您明白了。另请注意,这[0]是必要的,因为xpath将返回一个匹配数组(您只需要第一个),并且强制(string)转换用于提取节点中包含的文本。

此外,您的 XML 是无效的,并且会因为标签&中出现的文字而被解析器拒绝。<info name="album">

于 2013-05-11T14:30:23.180 回答
1

如果您再次查看您的代码,您会丢失一个函数,该函数将 xpath 表达式的第一个结果转换为 SimpleXMLElement 的字符串(转换)。

编写一次的一种方法是从SimpleXMLElement扩展

class BetterXMLElement extends SimpleXMLElement
{
    public function xpathString($expression) {
        list($result) = $this->xpath($expression);
        return (string) $result;
    }
}

然后,您创建更具体的 SimpleXMLElement,就像您之前使用的不太具体的一样:

$file = file_get_contents('http://192.168.0.15:8080/requests/status.xml');
$sxe  = new BetterXMLElement($file);

然后您将从以下代码中受益:

$artist = $sxe->xpathString('//info[@name="artist"]');
$album  = $sxe->xpathString('//info[@name="album"]');
$title  = $sxe->xpathString('//info[@name="title"]');

echo "<B>Artist: </B>".$artist."</br>";
echo "<B>Title: </B>".$title."</br>";
echo "<B>Album: </B>".$album."</br>";

这为您节省了一些重复的代码。这也意味着您可以在 :) 中犯错误的地方更少

当然,您可以通过允许传递多个 xpath 查询的数组并返回所有命名的值来进一步优化它。但这是您需要根据您的特定需求编写自己的东西。所以用你在编程中学到的东西让编程更容易:)

如果您需要更多建议,这里是另一个使用DOMDocument的非常详细的示例,它是SimpleXML的姊妹库。它非常先进,但可能会给您一些很好的启发,我认为 SimpleXML 也可以进行类似的操作,这可能就是您最终要寻找的东西:

于 2013-05-12T21:19:23.467 回答