Hello,
I'd suggest using the PHPXPath class. It's free to use and a single
PHP file that can be included in your PHP.
You can download it at Sourceforge:
http://sourceforge.net/projects/phpxpath/
There's a new version 3 out, which is in beta stage. You can either
use this one or the stable 2x version.
Supposedly version 3 wins a lot in speed, but in my own tests this was
almost irrelevant -- however, I found some bugs in the version 3
unless you download the latest source release directly from the CVS
Repository:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/phpxpath/Php.XPath/XPath-V3/
(In any case, the authors listen to your feedback via mailing list or
personal email.)
Here's a small sample that should give you an idea:
$xPath = new XPath();
$xPath->importFromString($xmlFileString);
$result = $xPath->match("//newsid | //channel");
$countResult = count($result);
for ($i = 0; $i < $countResult; $i++)
{
echo $xPath->getData($result[$i]);
}
(There's also more elaborate help and documentation coming with the
downloads from Sourceforge.)
XPath, as opposed to XML DOM, allows you more flexible and precise XML
parsing. However, both XML DOM and XML XPath require the complete
document tree to be build. So if you have a very large XML file to
parse, I'd suggest using an XML SAX solution. These are by far not as
intuitive to use in my personal opinion, as they are event-oriented
(but tell me if you specifically need SAX as I also have some
samples).
You can also find more information on PHP and XML on the official help
site:
http://www.php.net/manual/en/ref.xml.php
However, many features are experimental or need support of certain
libraries, so I found the mentioned XPath-Class to be a nice,
easy-to-use and implement alternative that doesn't require the latest
PHP installation on your server. But you say that you can compile
required modules, so it might be of interest.
Also, the XPath language specification at W3C:
http://www.w3.org/TR/xpath
Hope that helps you. |
Clarification of Answer by
j_philipp-ga
on
22 May 2002 05:50 PDT
I just took a closer look at your quoted XML file, and just to let you
know to not take my sample literally, as "newsId" in your case is an
attribute, and not an element. Of course you can also return elements
with specific attributes using an XPath like the following:
"//news[@sorting = 'tips']"
|
Request for Answer Clarification by
securityfocus-ga
on
22 May 2002 08:25 PDT
please post a working script i can use. i think this is not so much
work as you are in-this now, but for me its a horror.
|
Clarification of Answer by
j_philipp-ga
on
22 May 2002 08:55 PDT
I hope the following can help you, as it's tested on your data.
Please note that it uses the XPath class which you can find at:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/phpxpath/Php.XPath/XPath-V3/XPath.class.php?rev=1.1&content-type=text/vnd.viewcvs-markup
(Please save as file [XPath.class.php].)
Also, this sample assumes the file "xml.xml" you referenced to be in
the same folder as the PHP.
------- to be saved as [index.php] ----------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Display</title>
</head>
<body>
<?
require_once("XPath.class.php");
$sXml = getFileText("xml.xml");
$xPath = new XPath();
$xPath->importFromString($sXml);
$result = $xPath->match("//news");
$countResult = count($result);
for ($i = 0; $i < $countResult; $i++)
{
$thisId = getAsXhtml( $xPath->getAttributes($result[$i],
"newsId") );
$thisDate = getAsXhtml( $xPath->getAttributes($result[$i],
"newsDate") );
$newsTitle = getAsXhtmlFromCdata(
$xPath->getData($result[$i] . "/newsTitle") );
echo "<p>";
echo "ID: " . $thisId . "<br />";
echo "Date: " . $thisDate . "<br />";
echo "<strong>Title: " . $newsTitle . "</strong>";
echo "</p>";
}
function getAsXhtml($text)
{
$text = str_replace("&", "&", $text);
$text = str_replace("<", "<", $text);
$text = str_replace(">", ">", $text);
return $text;
}
function getAsXhtmlFromCdata($text)
{
$text = str_replace("<![CDATA[", "", $text);
$text = str_replace("]]>", "", $text);
return $text;
}
function getFileText($filePath)
{
$fileText = "";
$fileArray = file($filePath);
$countFile = count($fileArray);
for ($i = 0; $i < $countFile; $i++)
$fileText .= $fileArray[$i];
return $fileText;
}
?>
</body>
</html>
------- end of sample ----------
|
Request for Answer Clarification by
securityfocus-ga
on
22 May 2002 09:03 PDT
you are great!
one small modification request: how to get also the content of the
message - there are x >= 1
<summary>blabla</summary>
fields, as "blabla" being the message.
can you please extract also this?
then i am very happy!
|
Clarification of Answer by
j_philipp-ga
on
22 May 2002 09:26 PDT
To also list the summaries, please replace the relevant part (just the
start, no functions) of the previous PHP sample with the following:
---------- sample start -----------
require_once("XPath.class.php");
$sXml = getFileText("xml.xml");
$xPath = new XPath();
$xPath->importFromString($sXml);
$result = $xPath->match("//news");
$countResult = count($result);
for ($i = 0; $i < $countResult; $i++)
{
$thisId = getAsXhtml( $xPath->getAttributes($result[$i],
"newsId") );
$thisDate = getAsXhtml( $xPath->getAttributes($result[$i],
"newsDate") );
$newsTitle = getAsXhtmlFromCdata( $xPath->getData($result[$i] .
"/newsTitle") );
echo "<p>";
echo "ID: " . $thisId . "<br />";
echo "Date: " . $thisDate . "<br />";
echo "<strong>Title: " . $newsTitle . "</strong><br />";
$summary = $xPath->match($result[$i] . "/article/summary");
$countSummary = count($summary);
for ($j = 0; $j < $countSummary; $j++)
{
$sSummary = $xPath->getData($summary[$j]);
$sSummary = getAsXhtmlFromCdata($sSummary);
if ($sSummary != "")
{
echo "<em>Summary " . $j . ": " . $sSummary .
"</em><br />";
}
}
echo "</p>";
}
---------- sample end -----------
To explain: I do the same as before when the news-array was created,
but this time for the summaries of a single news article. To do so, I
pass the context of the current news-XPath to the XPath match()
routine.
Hope that helps you.
|