Parse XML and echo results - php

I'm just learning PHP. I have a bunch of scripts I have started and one has me stuck. I'm fetching an xml and printing the results to the page. However I only want the rows where the refTypeID = 10 and also I need to trim the text "DESC:" out of the reason area.
My current code
<?php
// Populate the following with your API Data
$vCode = "XXXXXXX";
$keyID = "XXXXXXX";
// Create the URL to the EVE API
$eveAPI = "http://api.eve-online.com/corp/WalletJournal.xml.aspx?keyID=".$keyID."&vCode=".$vCode."";
// Get the xml data
$xml = simplexml_load_file($eveAPI);
// Loop Through Skills
foreach ($xml->result->rowset->row as $value) {
echo "Skill Number:".$value['refTypeID']." -- Skill Points: ".$value['ownerName1']." -- Level: ".$value['reason']."<br />";
};
?>
What I'm parsing
<eveapi version="2">
<currentTime>2012-11-12 10:36:35</currentTime>
<result>
<rowset name="entries" key="refID" columns="date,refID,refTypeID,ownerName1,ownerID1,ownerName2,ownerID2,argName1,argID1,amount,balance,reason">
<row date="2012-11-12 10:46:49" refID="6570815512" refTypeID="10" ownerName1="Captain Vampire" ownerID1="159434479" ownerName2="The Condemned and Convicted" ownerID2="98032142" argName1="" argID1="0" amount="5000000.00" balance="13072537.98" reason="DESC: something "/>
<row date="2012-11-10 02:27:48" refID="6561124130" refTypeID="85" ownerName1="CONCORD" ownerID1="1000125" ownerName2="Justin Schereau" ownerID2="90541382" argName1="Unertek" argID1="30002413" amount="42300.00" balance="7972463.03" reason="10015:1,10019:1,11899:1,22822:1,"/>
<row date="2012-11-09 23:27:24" refID="6560673105" refTypeID="85" ownerName1="CONCORD" ownerID1="1000125" ownerName2="Blackcamper" ownerID2="754457655" argName1="Illamur" argID1="30002396" amount="25000.00" balance="7930163.03" reason="11898:1,"/>
</rowset>
</result>
<cachedUntil>2012-11-12 11:03:35</cachedUntil>
</eveapi>
Any help would be much appreciated
Thanks

You can use xpath directly as below
$xml = simplexml_load_file($eveAPI);
/* Search for <a><b><c> */
$result = $xml->xpath('//result/rowset/row[#refTypeID=10]');
foreach($result as $value) {
echo $value['reason'] = trim(str_replace('DESC:','',$value['reason']));
echo "Skill Number:".$value['refTypeID']." -- Skill Points: ".$value['ownerName1']." -- Level: ".$value['reason']."<br />";
}

Try
// Loop Through Skills
foreach ($xml->result->rowset->row as $value) {
if($value['refTypeID'] == 10){
echo "Skill Number:".$value['refTypeID']." -- Skill Points: ".$value['ownerName1']." -- Level: ".str_replace('DESC:', '', $value['reason'])."<br />";
}
};

You can use continue to skip rows you don't need :
foreach ($xml->result->rowset->row as $value) {
if ($value['refTypeID'] != "10") {
// skip
continue;
}
//etc ...
}
and use str_replace for remove the DESC: form your string:
$reason = str_replace('DESC: ','',$value['reason']);
NOTE: this also removes the space after DESC:

Related

How to loop through two XML files and print result

I've been trying unsuccessfully with PHP to loop through two XML files and print the result to the screen. The aim is to take a country's name and output its regions/states/provinces as the case may be.
The first block of code successfully prints all the countries but the loop through both files gives me a blank screen.
The countries file is in the format:
<row>
<id>6</id>
<name>Andorra</name>
<iso2>AD</iso2>
<phone_code>376</phone_code>
</row>
And the states.xml:
<row>
<id>488</id>
<name>Andorra la Vella</name>
<country_id>6</country_id>
<country_code>AD</country_code>
<state_code>07</state_code>
</row>
so that country_id = id.
This gives a perfect list of countries:
$xml = simplexml_load_file("countries.xml");
$xml1 = simplexml_load_file("states.xml");
foreach($xml->children() as $key => $children) {
print((string)$children->name); echo "<br>";
}
This gives me a blank screen except for the HTML stuff on the page:
$xml = simplexml_load_file("countries.xml");
$xml1 = simplexml_load_file("states.xml");
$s = "Jamaica";
foreach($xml->children() as $child) {
foreach($xml1->children() as $child2){
if ($child->id == $child2->country_id && $child->name == $s) {
print((string)$child2->name);
echo "<br>";
}
}
}
Where have I gone wrong?
Thanks.
I suspect your problem is not casting the name to a string before doing your comparison. But why are you starting the second loop before checking if it's needed? You're looping through every single item in states.xml needlessly.
$countries = simplexml_load_file("countries.xml");
$states = simplexml_load_file("states.xml");
$search = "Jamaica";
foreach($countries->children() as $country) {
if ((string)$country->name !== $search) {
continue;
}
foreach($states->children() as $state) {
if ((string)$country->id === (string)$state->country_id) {
echo (string)$state->name . "<br/>";
}
}
}
Also, note that naming your variables in a descriptive manner makes it much easier to figure out what's going on with code.
You could probably get rid of the loops altogether using an XPath query to match the sibling value. I don't use SimpleXML, but here's what it would look like with DomDocument:
$search = "Jamaica";
$countries = new DomDocument();
$countries->load("countries.xml");
$xpath = new DomXPath($countries);
$country = $xpath->query("//row[name/text() = '$search']/id/text()");
$country_id = $country[0]->nodeValue;
$states = new DomDocument();
$states->load("states.xml");
$xpath = new DomXPath($states);
$states = $xpath->query("//row[country_id/text() = '$country_id']/name/text()");
foreach ($states as $state) {
echo $state->nodeValue . "<br/>";
}

Get a web page XML code using php and use XPATH on it

Maybe its a question answered before but im so noobie in Web Development.
Im trying to get a full XML text from this page:
Human Genome
And, I need to do some XPath queries in that code, like "get the ID" and others.
For example:
//eSearchResult/IdList/Id/node()
How I can to get the full XML in a php object to request data throught XPath queries?
I used this code before:
<?php
$text = $_REQUEST['text'];
$xmlId = simplexml_load_file('https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=gene&term='.$text.'%5bGene%20Name%5d+AND+%22Homo%20sapiens%22%5bOrganism');
$id = $xmlId->IdList[0]->Id;
$xmlGeneralData = simplexml_load_file('https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=gene&id='.$id.'&retmode=xml');
$geneName = $xmlGeneralData->DocumentSummarySet->DocumentSummary[0]->Name;
$geneDesc = $xmlGeneralData->DocumentSummarySet->DocumentSummary[0]->Description;
$geneChromosome = $xmlGeneralData->DocumentSummarySet->DocumentSummary[0]->Chromosome;
echo "Id: ".$id."\n";
echo "Name: ".$geneName."\n";
echo "Description: ".$geneDesc."\n";
echo "Chromosome: ".$geneChromosome."\n";?>
But, according with the profesor, this code doesn't use Xpath queries and is required that the page use it.
Someone can help me or explain me how to do it?
Here's converted code to Xpath query.
<?php
$text = $_REQUEST['text'];
$xmlId = 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=gene&term='.$text.'%5bGene%20Name%5d+AND+%22Homo%20sapiens%22%5bOrganism';
//Load XML and define Xpath
$xml_id = new DOMDocument();
$xml_id->load($xmlId);
$xpath = new DOMXPath($xml_id);
//Xpath query to get ID
$elements = $xpath->query("//eSearchResult/IdList/Id");
//Loop through result of xpath query and store in array of ID
if ($elements->length >0) {
foreach ($elements as $entry) {
$id[] = $entry->nodeValue;
}
}
echo "Id: ".$id[0]."\n";
//Output the first string of ID array from xpath result set
$xmlGeneralData = 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=gene&id='.$id[0].'&retmode=xml';
//Load XML and define Xpath
$xml_gd = new DOMDocument();
$xml_gd->load($xmlGeneralData);
$xpath = new DOMXPath($xml_gd);
//Xpath query to search for Document Summary with first string of ID array from previous result set
$elements = $xpath->query("//eSummaryResult/DocumentSummarySet/DocumentSummary[#uid='".$id[0]."']");
//Loop through result of xpath query and find nodes and print out the result
if ($elements->length >0) {
foreach ($elements as $entry) {
echo "Name: ".$entry->getElementsByTagName('Name')->item(0)->nodeValue."\n";
echo "Description: ".$entry->getElementsByTagName('Description')->item(0)->nodeValue."\n";
echo "Chromosome: ".$entry->getElementsByTagName('Chromosome')->item(0)->nodeValue."\n";
}
}
?>

How do I fix this PHP code?

I have to create a live search on a website. I have to use PHP, but I have never studied it and I am pretty much a beginner in programming.
I have an XML-file as a database and the aim is to get node values and display them as suggestions as a user types in something. The problem with this code is that it spits out all of the node values onto the web page.
Here is the PHP code:
<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("collection.xml");
$books = $xmlDoc->getElementsByTagName("book");
$q = $_GET["q"];
if (strlen($q) > 0) {
$hint = "";
foreach ($books as $book) {
$name = $book->getElementsByTagName("name")->item(0)->nodeValue;
echo "$name <br/>";
}
}
if ($hint == "")
{
$response="no suggestion";
}
else
{
$response=$hint;
}
//output the response
echo $response;
?>
Here is the XML-file:
<books>
<book>
<name>Harry Potter</name>
<quantity> 50 </quantity>
<price>19.90</price>
</book>
<book>
<name>Casino Royale</name>
<quantity> 50 </quantity>
<price>12.99</price>
</book>
<book>
<name>The Great Gatsby</name>
<quantity> 40 </quantity>
<price>14.90</price>
</book>
</books>
Can someone please help me fix this issue so that I can continue working on my project. Thank you in advance for your time and help! Aprreciate it a lot!
The issue is here:
$hint = "";
foreach ($books as $book) {
$name = $book->getElementsByTagName("name")->item(0)->nodeValue;
echo "$name <br/>";
}
Notice that you have a "foreach loop" here. The "$name=$book...." line simply reads the value of that particular XML node and assigns it to the $name variable. Then you are doing a call to echo $name. So in essence, all you're doing here is reading the value of the XML node and printing it. No part of your code compares the $name to your search query ($q). It seems that what you want to happen is only print out books that somehow match $q.
In order to do that we need to apply some logic to your foreach loop to only print out values that match $q.
Here is a suggestion:
$hint = "";
foreach ($books as $book) {
$name = $book->getElementsByTagName("name")->item(0)->nodeValue;
// Let's only show this book if $q appears somewhere in $name.
if (strpos($name, $q) !== false && strpos($name, $q) >= 0)
{
echo $name . "<br />";
}
}

how to use loop for array

I have a array which it reads its cells from a xml file,i wrote it by "for" but now because i don't know how many node i have i wanna to write this loop in a way that it start and finish up to end of xml file.my code with for is:
$description=array();
for($i=0;$i<2;$i++)
{
$description[$i]=read_xml_node("dscription",$i);
}
and my xml file:
<eth0>
<description>WAN</description>
</eth0>
<eth1>
<description>LAN</description>
</eth1>
in this code i must know "2",but i wanna to know a way that doesn't need to know "2".
i am not sure what kind of parser you are using, but it is very easy with simplexml, so i put together some sample code using simplexml.
something like this should do the trick:
$xmlstr = <<<XML
<?xml version='1.0' standalone='yes'?>
<node>
<eth0>
<description>WAN</description>
</eth0>
<eth1>
<description>LAN</description>
</eth1>
</node>
XML;
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml as $xmlnode) {
foreach ($xmlnode as $description) {
echo $description . " ";
}
}
output:
WAN LAN
$length = count($description);
for ($i = 0; $i < $length; $i++) {
print $description[$i];
}
The parser you use might allow you to use a while loop which will return false when it has reached the end of the XML document. For example:
while ($node = $xml->read_next_node($mydoc)) {
//Do whatever...
}
If none exists, you can try using count() as the second parameter of your for loop. It returns the length of an array you specify. For example:
for ($i = 0; $i < count($myarray); $i++) {
//Do whatever...
}

PHP: $_POST array to XML file and display results

I'm creating a "Madlibs" page where visitors can create funny story things online. The original files are in XML format with the blanks enclosed in XML tags
(Such as blablabla <PluralNoun></PluralNoun> blablabla <Verb></Verb> ).
The form data is created using XSL and the results are saved using a $_POST array. How do I post the $_POST array between the matching XML tags and then display the result to the page? I'm sure it uses a "foreach" statement, but I'm just not familiar enough with PHP to figure out what functions to use. Any help would be great.
Thanks,
E
I'm not sure if I understood your problem quite well, but I think this might help:
// mocking some $_POST variables
$_POST['Verb'] = 'spam';
$_POST['PluralNoun'] = 'eggs';
// original template with blanks (should be loaded from a valid XML file)
$xml = 'blablabla <PluralNoun></PluralNoun> blablabla <Verb></Verb>';
$valid_xml = '<?xml version="1.0"?><xml>' . $xml . '</xml>';
$doc = DOMDocument::loadXML($valid_xml, LIBXML_NOERROR);
if ($doc !== FALSE) {
$text = ''; // used to accumulate output while walking XML tree
foreach ($doc->documentElement->childNodes as $child) {
if ($child->nodeType == XML_TEXT_NODE) { // keep text nodes
$text .= $child->wholeText;
} else if (array_key_exists($child->tagName, $_POST)) {
// replace nodes whose tag matches a POST variable
$text .= $_POST[$child->tagName];
} else { // keep other nodes
$text .= $doc->saveXML($child);
}
}
echo $text . "\n";
} else {
echo "Failed to parse XML\n";
}
Here is PHP foreach syntax. Hope it helps
$arr = array('fruit1' => 'apple', 'fruit2' => 'orange');
foreach ($arr as $key => $val) {
echo "$key = $val\n";
}
and here is the code to loop thru your $_POST variables:
foreach ($_POST as $key => $val) {
echo "$key = $val\n";
// then you can fill each POST var to your XML
// maybe you want to use PHP str_replace function too
}

Categories