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
Related
I know how to access tags in XML using PHP but this time, I have to use a function getText($textId) to access text content in those tags but I tried so many things that I am desperate for help.
I tried this
$doc->load("localisations_EN.xml");
$texts = $doc->getElementsByTagName("txt");
$elem = $doc->getElementById("home");
$children = $elem->childNodes;
foreach ($children as $child) {
if ($child->nodeType == XML_CDATA_SECTION_NODE) {
echo $child->textContent . "<br/>";
}
}
print_r($texts);
print_r($doc->getElementById('home'));
foreach ($texts as $text)
{
foreach($text->childNodes as $child) {
if ($child->nodeType == XML_CDATA_SECTION_NODE) {
echo $child->textContent . "<br/>";
}
}
}
Then I tried this but I don't know how to access the string value
$xml=simplexml_load_file("localisations_EN.xml") or die("Error: Cannot create object");
print_r($xml);
$description = $xml->xpath("//txt[#id='home']");
var_dump($description);
And I got something like this
array(1) { [0]=> object(SimpleXMLElement)#2 (1) { ["#attributes"]=>
array(1) { ["id"]=> string(4) "home" } } }
This is the XML file I have to use
<?xml version="1.0" encoding="UTF-8" ?>
<localisation application="test1">
<part ID="menu">
<txt id="home"><![CDATA[Home]]></txt>
<txt id="news"><![CDATA[News]]></txt>
<txt id="settings"><![CDATA[Settings]]></txt>
</part>
<part ID="login">
<txt id="id"><![CDATA[Login]]></txt>
<txt id="password"><![CDATA[Password]]></txt>
<txt id="forgetPassword"><![CDATA[Forget password?]]></txt>
</part>
</localisation>
Thanks for your help.
simplexml element has a __toString() magic function that will return the text content of the element (however, not the text content of sub-elements)
so your simplexml code should be
$xml=simplexml_load_file("localisations_EN.xml");
$description = (string) $xml->xpath("//txt[#id='home']")[0];
// ^-- triggers __toString() ^-- xpath returns array
because xpath returns an array of elements, you need to fetch one (or more) and cast it to string. To get the immediate contents of that element.
with DOMDocument:
don't know why you go for the (non-existant) child nodes there. CDATA is just syntax to say "don't parse this, this is data"
$doc = new DOMDocument;
$doc->load("localisations_EN.xml");
$texts = $doc->getElementsByTagName('txt');
foreach($texts as $text) {
if($text->getAttribute('id') == 'home') {
// prepend hasAttribute('id') if needed to if clause above
$description = $text->textContent;
}
}
also, $doc->getElementById() probably only works, if the DTD has set some attribute as ID. Since your xml doesn't do that (it doesn't name a DTD) it doesn't work.
with DOMDocument and DOMXPath
// $doc as before
$xpath = new DOMXPath($doc);
$description = $xpath->evaluate('//txt[#id="home"]')[0]->textContent;
// as before, xpath returns an array, that's why ---^
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 " - ";
}
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
I want to grab data from a xml file from a remote location which contains CDATA information in all nodes as listed below.
I use the following PHP function to grab such information but it doesn't work and seems not to be able to catch CDATA tags from xml file.
the question is whether my piece of code is correct or not ? and if it's wrong can you suggest any php code to get requested information?
<Items>
<Item ID="1">
<Name>Mountain</Name>
<Properties>
<Property Code="feature"><![CDATA[<ul><li>sample text</li></ul>]]></Property>
<Property Code="SystemRequirements"><![CDATA[Windows XP/Windows Vista]]></Property>
<Property Code="Description" Type="plain"><![CDATA[sample text2]]></Property>
</Properties>
</Item>
<Items>
and this is my php code :
<?
function xmlParse($file, $wrapperName, $callback, $limit = NULL) {
$xml = new XMLReader();
if (!$xml->open($file)) {
die("Failed to open input file.");
}
$n = 0;
$x = 0;
while ($xml->read()) {
if ($xml->nodeType == XMLReader::ELEMENT && $xml->name == $wrapperName) {
while ($xml->read() && $xml->name != $wrapperName) {
if ($xml->nodeType == XMLReader::ELEMENT) {
//$subarray[]=$xml->expand();
$doc = new DOMDocument('1.0', 'UTF-8');
$simplexml = simplexml_import_dom($doc->importNode($xml->expand(), true));
$subarray[]=$simplexml;
}
}
if ($limit == NULL || $x < $limit) {
if ($callback($subarray)) {
$x++;
}
unset($subarray);
}
$n++;
}
}
$xml->close();
}
echo '<pre>';
function func1($s) {
print_r($s);
}
xmlParse('myfile.xml', 'Item', 'func1', 100);
When I print this object by print_r($s); I can't see CDATA in result !.
do you have any idea in order to retrieve CDATA context ?
Treat it like a string
$file = "1.xml";
$xml = simplexml_load_file($file);
foreach($xml->Item->Properties->children() as $properties) {
printf("%s", $properties);
}
Output
<ul><li>sample text</li></ul>
Windows XP/Windows Vista
sample text2
There is allways way to use DOMDocument to open xml files, for example:
$xmlFile = new DOMDocument();
$xmlFile->load(myfile.xml);
echo $xmlFile->getElementsByTagName('Property')->item(0)->nodeValue;
I have a large (~30Mb) XML file like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<LIC Version="2.0" Title="Products">
<Item>
<Field Name="Filename">/root/_DOWNLOAD/Bird.txt</Field>
<Field Name="Read_By">Lisa Hannigan</Field>
<Field Name="Posit">Passenger</Field>
</Item>
<Item>
<Field Name="Filename">D:\03\Strypers.pdf</Field>
<Field Name="Read_By">Stryper</Field>
<Field Name="Intensity">2</Field>
<Field Name="IMG">78</Field>
<Field Name="Rotate">0</Field>
</Item>
<Item>
<Field Name="Filename">D:\Afriu.txt</Field>
<Field Name="Read_By">Africano</Field>
<Field Name="Posit">Canto Africano vol.1</Field>
<Field Name="File_Resource">mp3</Field>
</Item>
<Item>
<Field Name="Filename">D:\_VARIOUS\Knots.pdf</Field>
<Field Name="Date">40624</Field>
</Item>
...
</LIC>
I want to import this xml into mysql database, with a php script. I've used SIMPLEXML and xpath:
$url = 'FILE.xml';
$xml = simplexml_load_file($url);
$result = $xml->xpath("//Field[#Name]");
foreach { ... }
What do i need? What is the correct "foreach" to create an array to use for mysql sql?
Notes that every row (identify by "Item") is not same (not have the same "Field Name").
Is it correct to use simplexml for larger file?
Thank you for help!
update
This is an example to use "foreach", i tried:
$result = $xml->xpath("//Field[#Name]");
foreach($result as $key => $value) {
echo $value['Name']."=".$value.",";
}
Now I want to find out how to create the string to insert in mysql
First create a table that matches all possible fields as columns. Then you can load it by a LOAD XML LOCAL INFILE query.
LOAD XML LOCAL INFILE 'file.xml'
INTO TABLE person
ROWS IDENTIFIED BY '<Item>';
I try to answer my question.
<?php
$url = 'FILEXML';
$xml = simplexml_load_file($url);
$i = 1;
foreach($xml->xpath("/LIC/Item") as $docs)
{
foreach($docs->Field as $field)
{
$resultstr[] = $field["Name"];
}
$sql_head = headquote($resultstr);
$sql_ins = "INSERT INTO table_name (";
$sql_dec = ") VALUE (";
unset($resultstr);
$fresult = (array)$docs;
$fvalue = array_pop($fresult);
$sql_val = numking($fvalue);
$sql_end = ");";
$query_to_use_for_mysql = ($sql_ins.$sql_head.$sql_dec.$sql_val.$sql_end);
unset($fresult);
unset($fvalue);
}
?>
And add this two functions:
<?php
function headquote($hdarray) {
$hdata = array();
foreach ( $hdarray as $hdval ) {
# Use backticks instead quotes!
$hdata[] = "`$hdval`";
}
$hdarray = implode($hdata, ',');
return $hdarray;
}
function numking($input) {
$data = array();
foreach ( $input as $value ) {
$data[] = is_numeric($value) ? $value : "'".mysql_escape_string($value)."'";
}
$input = implode($data, ',');
return $input;
}
?>
Thanks to all for help!
$url = 'FILE.xml';
$xml = simplexml_load_file($url);
for($i=0;$i<count($xml->Item);$i++)
{
print_r($xml->Item[$i]);
}