【发布时间】:2015-11-09 05:06:31
【问题描述】:
我整天都在为此苦苦挣扎,实际上它可能真的很简单......但我是 PHP 和 XML 世界的初学者,所以真的可以在一些帮助下做。
我正在使用 SimpleXML 来解析我的数据并有两个二级组 - (yearlist) 和 (eplist)。我有 (year) 嵌套在 (yearlist) 里面,它有一个属性“yid”,在我的 DTD 中设置为 ID。它还有 (yearname) 嵌套在 (year) 中,其中包含要显示为输出的更详细的描述。我有 (ep) 嵌套在 (eplist) 中,属性“yearid”(与“yid”直接相关),在我的 DTD 中设置为 IDREF。
基本上,当我解析 (eplist) 的数据时,我想使用 (yearname) 作为组头 - 使用 yearid=yid>yearname 作为路径。
我创建了一个数据示例,这可能有助于更好地解释我的问题。
这是我的 DTD:
<?xml encoding="UTF-8"?>
<!ELEMENT besteplist (yearlist,eplist)>
<!ELEMENT yearlist (year)+>
<!ELEMENT year (yearname)>
<!ATTLIST year
yid ID #REQUIRED>
<!ELEMENT yearname (#PCDATA)>
<!ELEMENT eplist (ep)+>
<!ELEMENT ep (eptitle,eptnumber)>
<!ATTLIST ep
eid ID #REQUIRED
yearid IDREF #IMPLIED>
<!ELEMENT eptitle (#PCDATA)>
<!ELEMENT eptnumber (#PCDATA)>
这是我的 XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE besteplist SYSTEM "example.dtd">
<besteplist>
<yearlist>
<year yid="y1">
<yearname>1995, Season 1</yearname>
</year>
<year yid="y2">
<yearname>1996, Season 2</yearname>
</year>
<year yid="y3">
<yearname>1997, Season 3</yearname>
</year>
</yearlist>
<eplist>
<ep yearid="y1" eid="e1">
<eptitle>The First Episode</eptitle>
<eptnumber>1</eptnumber>
</ep>
<ep yearid="y2" eid="e2">
<eptitle>Bla bla bla</eptitle>
<eptnumber>21</eptnumber>
</ep>
<ep yearid="y2" eid="e3">
<eptitle>Rar rar rar</eptitle>
<eptnumber>39</eptnumber>
</ep>
<ep yearid="y2" eid="e4">
<eptitle>Tra la la</eptitle>
<eptnumber>45</eptnumber>
</ep>
<ep yearid="y3" eid="e5">
<eptitle>Donkey</eptitle>
<eptnumber>126</eptnumber>
</ep>
</eplist>
</besteplist>
这是我希望输出的示例:
SEASON: 1995, Season 1
EPISODE TITLE: The First Episode
EPISODE NUMBER: 1
SEASON: 1996, Season 2
EPISODE TITLE: Bla bla bla
EPISODE NUMBER: 21
EPISODE TITLE: Rar rar rar
EPISODE NUMBER: 39
EPISODE TITLE: Tra la la
EPISODE NUMBER: 45
SEASON: 1997, Season 3
EPISODE TITLE: Donkey
EPISODE NUMBER: 126
我认为发布我已经尝试过的代码没有多大用处,因为它可能相当无用......我已经设法做的是非常基础的。一旦我完成了这个,我就可以进入下一个阶段......格式化......
我不以任何方式依附于 SimpleXML,所以如果有人能建议一种更有效的做事方式,我会全力以赴。
非常感谢任何花时间帮助我的人。 :)
山姆
作为对@michi 的回应,我一直在努力研究 xpath 并在线阅读各种语法/教程,但似乎无法理解它。这是我到目前为止所拥有的......但我已经注释掉了 xpath,因为它显然是错误的。
<?php
$xml=simplexml_load_file("example.xml") or die("Error: Cannot create object");
foreach($xml->yearlist->children() as $years) {
$xyid=$years[yid];
echo "_____________________________________________<br>";
echo "(yid= " . $xyid . " )<br>";
echo "SEASON: " . $years->yearname . "<br>";
echo "_____________________________________________<br>";
foreach($xml->eplist->children() as $episodes) {
echo "EPISODE TITLE: " . $episodes->eptitle . "<br>";
echo "EPISODE NUMBER: " . $episodes->eptnumber . "<br>";
$xyearid=$episodes[yearid];
echo "(yearid= " . $xyearid . " )<br>";
// echo $xml->xpath('//year[@yid="$episodes[yearid]"]/yearname');
echo "</p>";
}
}
?>
希望你能指引我正确的方向!
谢谢 山姆
感谢 michi 的帮助 - 这绝对是朝着正确方向迈出的一步!
我正在想办法只显示一次季节名称...遇到了迭代和数组,但它们对我来说都太复杂了。是否可以在 foreach 命令中包含 xpath?我想也许如果我在 foreach 季节中嵌套 foreach 剧集并使用 xpath 来匹配它可以工作的 ID,但我似乎无法让它显示元素。我在正确的轨道上吗?
<?php
$xml=simplexml_load_file("example.xml") or die("Error: Cannot create object");
foreach ($xml->yearlist->year as $season) {
echo "SEASON: " . $season->yearname . PHP_EOL;
foreach ($xml->xpath("//ep[@yearid='$season[yid]']")[0] as $episode) {
echo "EPISODE TITLE: " . $episode->eptitle . PHP_EOL;
echo "EPISODE NUMBER: " . $episode->eptnumber . PHP_EOL;
echo PHP_EOL;
}
}
?>
再次感谢!
【问题讨论】:
-
你做到了,只需删除
foreach中的[0],请参阅 eval.in/465031。我一直在考虑另一种方法,因为经常有很多方法可以实现目标。我将在我的回答中详细说明替代方案。
标签: php xml xml-parsing simplexml dtd