Re: METS/XML Search facility
| From: | Dan Field | Date: | Mon, 27 Sep 2004 13:34:07 +0000 |
| Subject: | Re: METS/XML Search facility | ||
| References: | 1 2 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-197950@lists.php.net to get a copy of this message | ||
Burhan Khalid wrote:
Dan Field wrote:$xml_repository = "/var/www/html/mets/sample/"; $searchable_tags = array("MODS:TITLE"); $current_data = ""; $dir_array = array(); $hits = 0; $MAXHITS = 100; $search_term = "William"; $validtag = false; $found = false;I'm trying to write an XML Document search engine specifically for METS encoded data ( http://www.loc.gov/standards/*mets*/ ). I've tried knocking together some proof of concept code in PHP4 using both DOM and xml_parser but I've run into dificulties with both. Can anyone point me at some code/class which enables me to search within an XML document for the existance of $string within a set list of tags eg. <METS:title>Some Title Here</METS:title> <METS:description>This is a description of this document</METS:description> It seems like a very straightforward task.You can do searching from the function that is designated as the character handler (if you are using the xml_* functions). You would just have to keep track of what tag you are checking by setting flags, etc. This is what I tried first off, but I found that I was getting forced breaks within the data for some reason. I believe certain characters caused the parser to stop and parse in multiple passes. I'm probably not explaining it very well, heres the code I was using:
function startElement($parser, $name, $attrs) {
global $depth, $searchable_tags, $current_data, $hits, $colour, $found, $search_term, $validtag;
if (in_array($name,$searchable_tags)) {
$validtag = true;
}
}
function characterData($parser, $data) {
global $current_data, $found, $validtag, $hits;
if ($validtag) {
if (preg_match("/".$search_term."/i",$current_data)) {
$found = true;
$hits++;
$data = trim($data);
$current_data .= $data;
}
}
}
function endElement($parser, $name) {
global $depth, $current_data, $found, $hits;
if ($found) {
echo "<div>hits:$hits current_data: $current_data</div><br />\n";
$found = false;
$current_data = "";
}
}
function search_data($term,$data) {
if (preg_match($term,$data)) { return true; } else { return false; }
}
// read all the xml files and parse through search engine
if ($handle = opendir($xml_repository)) {
$i = 0;
while (false !== ($file = readdir($handle))) {
$dir_array[$i] = $file;
$i ++;
}
closedir($handle);
}
for ($i = 2; $i < count($dir_array); $i++) {
$xml_parser = xml_parser_create("UTF-8");
xml_parser_set_option ($xml_parser,$XML_OPTION_SKIP_WHITE ,1);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($xml_repository.$dir_array[$i], "r"))) {
die("could not open XML input");
}
while ($data = fread($fp, 4096)) {
if ($hits >= $MAXHITS) { echo "<p><b>over 100 hits!\n</b> Stopping here.</p>"; exit; }
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}
}
xml_parser_free($xml_parser);
}
I tried handing values out from characterData() into a global but this just plain didn't work. Only the concatenation operator seemed to work here and this wasn't what I wanted.
--
Dan Field <dof@llgc.org.uk>
Support Programmer: Cymru ar y we / Wales on the Web
cy_GB: http://www.cymruarywe.org
en_GB: http://www.walesontheweb.org