simplexml_load_file with <m:properties> [duplicate] - php

The xml data looks like this:
<feed>
<entry>
<abc:rank scheme="http://foo.bar">45</abc:rank>
<abc:rank scheme="http://foo2.bar">88</abc:rank>
</entry>
<entry>
<abc:rank scheme="http://foo.bar">125</abc:rank>
<abc:rank scheme="http://foo2.bar">32</abc:rank>
</entry>
</feed>
I am able to output all of these entries with this code:
foreach($xml->entry[$i]->children('abc', true) as $a) {
echo $a;
}
However, if I want to get the one with the content "88" in the first entry, something like
foreach($xml->entry[$i]->children('abc', true) as $a) {
if($a["scheme"] == "http://foo2.bar")
echo $a;
}
does not work.
How can I select these children depending on their attribute?

Ok I got it by now. For those interested in the correct solution:
$namespaces = $xml->entry[$i]->getNameSpaces('true');
$abc= $xml->entry[$i]->children($namespaces['abc']);
foreach($abc->rank as $a) {
$scheme = $a->attributes();
echo $scheme['scheme'];
echo " - ";
}

Related

PHP Array Comparison using If

I am having a hard time trying to understand why I can't compare the values of two arrays in PHP. If I echo both of these during the loop using "echo $description->ItemDesriptionName;" and "echo $item->ItemName;" the values seem to show as the same, but when I try to compare them using if, nothing works. What am I missing?
<?php
$xml=simplexml_load_file("test.xml") or die("Error: Cannot create object");
$categories = $xml->Menu->Categories;
$items = $xml->Menu->Categories->Items->ItemObject;
$itemdescription = $xml->Menu->Options->Description->DescriptionObject;
foreach($items as $item) {
echo $item->ItemName . ' - ' . $item->Price . '</br>';
foreach ($itemdescription as $description) {
if ($description->ItemDescriptionName == $item->ItemName) {
echo 'We have a match!';
//where I would echo $description->ItemDescription;
}
}
}
?>
Here is the XML file
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Menu>
<Categories>
<Name>Category 1</Name>
<Items>
<ItemObject>
<ItemName>Item 1</ItemName>
<Price>1</Price>
</ItemObject>
<ItemObject>
<ItemName>Item 2</ItemName>
<Price>3</Price>
</ItemObject>
</Items>
</Categories>
<Options>
<Description>
<DescriptionObject>
<ItemDescriptionName>Item 1</ItemDescriptionName>
<ItemDescription>A Great item</ItemDescription>
</DescriptionObject>
<DescriptionObject>
<ItemDescriptionName>Item 2</ItemDescriptionName>
<ItemDescription>A Great item as well</ItemDescription>
</DescriptionObject>
</Description>
</Options>
</Menu>
</Root>
compare as string
and you have typo in ItemDescriptioName (ItemDescriptionName)
if ( (string)$description->ItemDescriptionName == (string)$item->ItemName) {
Convert to string and then compare
<?php
$xml=simplexml_load_file("test.xml") or die("Error: Cannot create object");
$menu = $xml->Menu;
$categories = $xml->Menu->Categories;
$items = $xml->Menu->Categories->Items->ItemObject;
$itemdescription = $xml->Menu->Options->Description->DescriptionObject;
foreach($items as $item) {
$itemname = $item->ItemName;
foreach ($itemdescription as $description) {
$descriptionname = $description->ItemDescriptionName ;
echo $itemname." ---- ".$descriptionname."<br/>";
if((string)$itemname === (string)$descriptionname){
echo "Yes its matched";
}
}
}
?>
Working fine for me
The properties like $description->ItemDescriptionName are SimpleXMLElement objects. So you do not compare strings but two objects.
SimpleXMLElement objects implement the magic method __toString(). They can be cast to string automatically, but a compare between to objects will not trigger that. You can force it:
if ((string)$description->ItemDescriptionName === (string)$item->ItemName) {
...
Can you access them directly instead using an accordant index?
...
$items = $xml->Menu->Categories->Items->ItemObject;
$itemdescription = $xml->Menu->Options->Description;
$i = 0;
foreach ($items as $item) {
echo $i.' '.$item->ItemName . ' - ' . $item->Price;
echo $itemdescription->DescriptionObject[$i]->ItemDescriptionName[0];
echo ' ';
echo $itemdescription->DescriptionObject[$i]->ItemDescription[0];
echo '</br>';
$i++;
}

Geting soap xsi:type from server response

I get response from SOAP server which has zero or more transactions of different types in each response.
Each transaction type is extension of base transaction type.
Different transaction types are processed differently.
Is there a way in PHP to get transaction type for each of transactions in response
(other then trying to figure difference in elements within each complex type)?
There is lot of types and lot of elements in each type....
Is there any class which could get this?
Following is just illustration...
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type1">
<id>24111</id><something>00000000</something><name>Blah</name>
</transactions>
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type8">
<id>24111</id><somethingelse>011</somethingelse>
</transactions>
I 'm not quite sure if this answer fits your question exactly. The following code snippet gets the type attribute value by their given namespaces and not the type of the namespaced value itself.
Done with PHP 's own Document Object Model.
<?php
$str = <<<XML
<content>
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type1">
<id>24111</id>
<something>00000000</something>
<name>Blah</name>
</transactions>
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type8">
<id>24111</id>
<somethingelse>011</somethingelse>
</transactions>
</content>
XML;
$doc = new DomDocument();
$doc->loadXML($str);
$nodeList = $doc->getElementsByTagName('transactions');
foreach ($nodeList as $element) {
$value = $element->getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'type');
echo $value . "\n";
}
This will output the two given types "ns2:type1" and "ns2:type8".
I can parse your elements with simple_html_dom.
Here is the link for it.
An example is here :
<?php
include "simple_html_dom.php";
$html_nb = '
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type1"><id>24111</id><something>00000000</something><name>Blah</name>
</transactions>
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type8"><id>24111</id><somethingelse>011</somethingelse>
</transactions>';
function chtml($str){
if(strpos("<html>", $str) !== false)
return '<html><whole_code>'.$str.'</whole_code></html>';
else
return "<whole_code>".$str."</whole_code>";
}
function find_element_type($str){
if(preg_match_all("/\<(.*?)\>/i", $str, $matches))
return $matches[1][0];
else
return false;
}
function get_xsi_type($str){
if(preg_match_all("/xsi\:type\=\"(.*?)\"/i", $str, $matches))
return $matches[1][0];
else
return false;
}
$html = new simple_html_dom();
$html_2 = new simple_html_dom();
$html->load(chtml($html_nb));
$max_type = 10;
$element = $html->find('whole_code');
$e = $element[0]->innertext;
$html_2->load(chtml($e));
$k = 0;
while($html_2->find("whole_code",false)->children($k) != "")
{
$all = $html_2->find("whole_code",false)->children($k);
echo get_xsi_type($all) . "<br>";
echo find_element_type($all) . " : " .$all."<br>";
$k++;
}
echo "<hr>";
The result :
ns2:type1
transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type1" : 2411100000000Blah
ns2:type8
transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:type8" : 24111011

Can I include an element from an xml file with php?

I have a list, consisting of links looking like this:
<a href=index.php?p=page_1>Page 1</a>
<a href=index.php?p=page_2>Page 2</a>
<a href=index.php?p=page_3>Page 3</a>
When clicked they include a page (page_1.inc.php or page_2.inc.php or page_3.inc.php) on my page thanks to this script:
<?php
$pages_dir = 'pages';
if(!empty($_GET['p'])){
$pages = scandir($pages_dir, 0);
unset($pages[0], $pages[1]);
$p = $_GET['p'];
if (in_array($p.'.inc.php', $pages)){
include ($pages_dir.'/'.$p.'.inc.php');
}
else {
echo 'Sorry, could not find the page!';
}
}
else {
include($pages_dir.'/home.inc.php');
}
?>
Period.
I also have an xml file looking like this:
<program>
<item>
<date>27/8</date>
<title>Page 1</title>
<info>This is info text</info>
</item>
<item>
<date>3/9</date>
<title>Page 2</title>
<info>This is info text again</info>
</item>
<item>
<date>10/9</date>
<title>Page 3</title>
<info>This just some info</info>
</item>
</program>
This is what I want to achieve:
If I click on the link "Page 1" it will display "This is info text" on the page.
If I click on the link "Page 2" it will display "This is info text again" on the page.
If I click on the link "Page 3" it will display "This just some info" on the page.
Was I clear enough?
Is there any solution for this?
You should be able to do this with SimpleXMLElement using the xpath() method.
$xmlString = file_get_contents("path/to/xml/file.xml");
$xml = new SimpleXMLElement($xmlString);
$info = $xml->xpath("/program/item[title='Page " . $page . "']/info");
echo (string) $info[0];
Update:
To get an array of all dates you would do something like this:
$xmlString = file_get_contents("path/to/xml/file.xml");
$xml = new SimpleXMLElement($xmlString);
$results = $xml->xpath("/program/item/date");
$dates = array();
if (!empty($results)) {
foreach ($results as $date) {
array_push($dates, (string) $date); // It's important to typecast from SimpleXMLElement to string here
}
}
Also, you could combine the logic, if needed, from the first and second examples. You can reuse the $xml object for multiple XPath queries.
If you need $dates to be unique, you can either add an in_array() check before doing the array_push() or you can use array_unique() after the foreach.

PHP: Need he!p with simple XML

I am beginner in PHP. I am trying to parse this xml file.
<relationship>
<target>
<following type="boolean">true</following>
<followed_by type="boolean">true</followed_by>
<screen_name>xxxx</screen_name>
<id type="integer">xxxx</id>
</target>
<source>
<notifications_enabled nil="true"/>
<following type="boolean">true</following>
<blocking nil="true"/>
<followed_by type="boolean">true</followed_by>
<screen_name>xxxx</screen_name>
<id type="integer">xxxxx</id>
</source>
</relationship>
I need to get the value of the field 'following type="boolean" ' for the target and here's my code -
$xml = simplexml_load_string($response);
foreach($xml->children() as $child)
{
if ($child->getName() == 'target')
{
foreach($child->children() as $child_1)
if ( $child_1->getName() == 'following')
{
$is_my_friend = (bool)$child_1;
break;
}
break;
}
}
but I am not getting the correct output. I think the ' type="boolean" ' part of the field is creating problems. Please help.
You could also use xpath for this.
foreach ($xml->xpath("//target/following[#type='boolean']") as $is_my_friend)
{
echo $is_my_friend;
}
$xml = simplexml_load_string($response);
foreach($xml->target->following as $child)
{
$is_my_friend = $child;
}
When casting a string to boolean in PHP, all values except the empty string and "0" are considered TRUE.
http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting

PHP Simple XML Parse Attributes

I have an XML file with data stored like this:
<myxml>
<item name="column18">88744544</item>
<item name="column11">47884994</item>
<item name="column3">44788894</item>
</myxml>
I need to first check (and be sure that) column11 is defined (there is no particular order), and then get its value.
Using simple XML is not seeming to work.
I have the following, but the value is missing.
<?php
if (count($xml->myxml->item) > 0)
{
foreach ($xml->myxml->item as $item)
{
var_dump($item->attributes());
}
}
?>
$item->attributes()->column11 doesn't work.
Dont include the opening tabs and attributes. For example:
<?php
if (count($xml->item) > 0)
{
foreach ($xml->item as $item)
{
var_dump($item); //For the info
echo $item['name']; //if you needed the name
}
}
?>
Try XPath.
if ($xml->xpath('//item[#name="column11"]'))
{
echo 'exists';
}

Categories