I have following code
public function returnArrayOfXmlElements(string $xml_path, string $element_key)
{
// Variables
$this->simplexml_array = (array)$this->returnSimpleXmlObject($xml_path);
// Variables With Dependencies
$this->xml_elements = $this->simplexml_array[$element_key];
foreach ($this->xml_elements as $this->array_key => $this->array_value) {
$this->xml_elements_rectified[] = (array)$this->array_value;
}
return $this->xml_elements_rectified;
}
When I try this,
switch ($menu_name) {
case 'secondary':
// Variables
$this->menu_directory = constant('ENVIRONMENT_DIRECTORY_FRONTEND_MENU_SECONDARY');
$this->request_uri = (empty($_GET['request']) !== TRUE ? $_GET['request'] : constant('SETTING_TEMPLATE_DEFAULT'));
// Variables With Dependencies
$this->section_name = strtolower(substr($this->request_uri, 0, strpos($this->request_uri, '/')));
$this->menu_file = $this->section_name.'.xml';
$this->menu_data = $this->library_xml->returnArrayOfXmlElements($this->menu_directory.$this->menu_file, 'item');
echo '
<ul menu-secondary>
<li class="icon"><icon id="section-'.$this->section_name.'"></icon></li>
';
foreach ($this->menu_data as $this->array_key => $this->menu_information) {
// Variables
$this->item_hook = $this->menu_information['hook'];
$this->item_name = $this->menu_information['name'];
echo '<li>'.$this->item_name.'</li>';
}
echo '
</ul>
';
break;
default:
// Variables
$this->menu_directory = constant('ENVIRONMENT_DIRECTORY_FRONTEND_MENU');
$this->menu_file = 'main.xml';
// Variables With Dependencies
$this->menu_data = $this->library_xml->returnArrayOfXmlElements($this->menu_directory.$this->menu_file, 'item');
echo '
<ul menu-main>
<li>polybotes</li>
';
foreach ($this->menu_data as $this->array_key => $this->menu_information) {
// Variables
$this->item_hook = $this->menu_information['hook'];
$this->item_name = $this->menu_information['name'];
echo '<li>'.$this->item_name.'</li>';
}
echo '
</ul>
';
break;
}
}
$this->menu_data from the secondary switch contains data of both $xml1 and $xml2. How can I prevent this?Unsetting $xml1 does not solve the problem.
The XML files look like this:
$xml1:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<menu>
<item>
<name>Dashboard</name>
<hook>/dashboard/view</hook>
</item>
<item>
<name>Location</name>
<hook>/location/list</hook>
</item>
<item>
<name>Networks</name>
<hook>/network/list</hook>
</item>
<item>
<name>Devices</name>
<hook>/device/list</hook>
</item>
<item>
<name>Alarms & Events</name>
<hook>/alarm/list</hook>
</item>
</menu>
$xml2:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<menu>
<item>
<name>Network List</name>
<hook>/network/list</hook>
</item>
<item>
<name>Add Network</name>
<hook>/network/add</hook>
</item>
</menu>
Could you please help me or point me in the right direction? Thanks in advance.
In your method returnArrayOfXmlElements you always seem to use $this->variableName, this can cause problems as it will retain data across method calls.
Unless you really need to retain this data, try removing the $this-> from each of the variables...
public function returnArrayOfXmlElements(string $xml_path, string $element_key) {
// Variables
$simplexml_array = (array)$this->returnSimpleXmlObject($xml_path);
// Variables With Dependencies
$xml_elements = $this->simplexml_array[$element_key];
$xml_elements_rectified = [];
foreach ($xml_elements as $this->array_key => $this->array_value) {
$xml_elements_rectified[] = (array)$this->array_value;
}
return $xml_elements_rectified;
}
Related
I wanted to try to pick up Volume value from the Level1Data node.
Here is the xml:
<Response>
<Content>
<Level1Data Tick="U" Currency="USD" TickSize="0.0001000000" TickValue="0" AssetClass="Equity" InstrumentState="Open" LastPrice="24.1550" LotSize="10"
MinPermittedPrice="0" MaxPermittedPrice="0" ClosePrice="24.0300" OpenPrice="24.1500" FirstPrice="24.1500"
HighPrice="24.7800" LowPrice="24.0000" MaxPrice="24.7800" MinPrice="24.0000" Volume="16238302"
AskSize="105597" BidSize="97618" AskPrice="24.1600" BidPrice="24.1500" Symbol="BAC.NY"
MarketTime="12:08:41.356" Message="L1DB"/>
</Content>
</Response>
And then my main script:
<?php
$result = file_get_contents("lvl1.xml");
// echo $result;
$xml = new SimpleXMLElement($result);
// $dom = new DOMDocument();
// $dom->loadXML("lvl1.xml");
// $vol = dom->getElementsByTagName('Level1Data');
$vol=$xml->children->children('Level1Data');
$id = $xml["Volume"];
echo $id;
?>
Nothing gets returned and I am having a hard time reading the php documentation and their examples.
Thank you.
You can try to find the XML node using attributes() and foreach what attribute you want as per your requirements. If you need only single attribute then discard foreach looping.
<?php
$result =<<<EOT
<Response>
<Content>
<Level1Data Tick="U" Currency="USD" TickSize="0.0001000000" TickValue="0" AssetClass="Equity" InstrumentState="Open" LastPrice="24.1550" LotSize="10"
MinPermittedPrice="0" MaxPermittedPrice="0" ClosePrice="24.0300" OpenPrice="24.1500" FirstPrice="24.1500"
HighPrice="24.7800" LowPrice="24.0000" MaxPrice="24.7800" MinPrice="24.0000" Volume="16238302"
AskSize="105597" BidSize="97618" AskPrice="24.1600" BidPrice="24.1500" Symbol="BAC.NY"
MarketTime="12:08:41.356" Message="L1DB"/>
</Content>
</Response>
EOT;
$volume = '';
$xml = new SimpleXMLElement($result);
foreach($xml->Content->Level1Data[0]->attributes() as $a => $b) {
if($a=='Volume'){
$volume = $b;
}
}
echo $volume;
?>
Demo https://eval.in/839942
OR for single attribute e.g Volume
echo $xml->Content->Level1Data[0]->attributes()->Volume;
If you want to pickup Volume only, it can also be done as follows.
<?php
$result = <<<EOM
<Response>
<Content>
<Level1Data Tick="U" Currency="USD" TickSize="0.0001000000" TickValue="0" AssetClass="Equity" InstrumentState="Open" LastPrice="24.1550" LotSize="10"
MinPermittedPrice="0" MaxPermittedPrice="0" ClosePrice="24.0300" OpenPrice="24.1500" FirstPrice="24.1500"
HighPrice="24.7800" LowPrice="24.0000" MaxPrice="24.7800" MinPrice="24.0000" Volume="16238302"
AskSize="105597" BidSize="97618" AskPrice="24.1600" BidPrice="24.1500" Symbol="BAC.NY"
MarketTime="12:08:41.356" Message="L1DB"/>
</Content>
</Response>
EOM;
$xml = new SimpleXMLElement($result);
echo $xml->Content->Level1Data[0]->attributes()->Volume;
EDIT
<?php
$result = <<<EOM
<Response>
<Content>
<Level1Data Tick="U" Currency="USD" TickSize="0.0001000000" TickValue="0" AssetClass="Equity" InstrumentState="Open" LastPrice="24.1550" LotSize="10"
MinPermittedPrice="0" MaxPermittedPrice="0" ClosePrice="24.0300" OpenPrice="24.1500" FirstPrice="24.1500"
HighPrice="24.7800" LowPrice="24.0000" MaxPrice="24.7800" MinPrice="24.0000" Volume="16238302"
AskSize="105597" BidSize="97618" AskPrice="24.1600" BidPrice="24.1500" Symbol="BAC.NY"
MarketTime="12:08:41.356" Message="L1DB"/>
</Content>
</Response>
EOM;
$xml = new SimpleXMLElement($result);
function recur($obj){
if ( in_array('Level1Data', array_keys( (array) $obj->children()) ) === false){
recur($obj->children());
}else{
var_dump($obj->children()->Level1Data);
exit;
}
}
recur($xml);
$var1 = new SimpleXMLElement('CSVXML/xvar.xml', null, true);
$var2 = new SimpleXMLElement('CSVXML/yvar.xml', null, true);
let's say I get variables from two diffrents XML files, in the first XML files
<Number>3698</Number>
<InternalNumber>1</InternalNumber>
<Name>Bob</Name>
<Number>3500</Number>
<InternalNumber>2</InternalNumber>
<Name>Mike</Name>
<Number>2775</Number>
<InternalNumber>3</InternalNumber>
<Name>Dan</Name>
in the second XML I get the followings
<player>3698</player>
<group>A</group>
I do this
$varID = $var1->Number;
$varnumber = $var2->player;
if ($varID == $varnumber ){
echo '$var1->InternalNumber';
}
is this possible ?
I simply want to put out a variable, is A for XML! = B from XML2, is there anyway possible to do that?
I found this working fine. tested link
<?php
$str = <<<XML
<items>
<item>
<Number>3698</Number>
<InternalNumber>1</InternalNumber>
<Name>Bob</Name>
</item>
<item>
<Number>3500</Number>
<InternalNumber>2</InternalNumber >
<Name>Mike</Name>
</item>
<item>
<Number>2775</Number>
<InternalNumber>3</InternalNumber>
<Name>Dan</Name>
</item>
</items>
XML;
$str2 = <<<XML
<item>
<player>3698</player>
<group>A</group>
</item>
XML;
$da = new SimpleXMLElement($str2);
$varnumber = $da->player;
$data = new SimpleXMLElement($str);
foreach ($data->item as $item)
{
$this_number = $item->Number;
//echo $this_number."-".$item->InternalNumber."-".$varnumber."\n";
if((int)$this_number == (int)$varnumber ){
$this_internalnumber = $item->InternalNumber;
echo $this_internalnumber."\n";
}
else{
echo "No Match found \n";
}
}
Hope this helps.
I want to read the following xml and find specific xml tags by their id values , Finally i want to copy these selected tags inside another xml using php user define class methods: sample given below:
<items>
<item>
<id>1</id>
<name>Item-1</name>
<price>10</price>
</item>
<item>
<id>2</id>
<name>Item-2</name>
<price>20</price>
</item>
<item>
<id>3</id>
<name>Item-3</name>
<price>30</price>
</item>
</items>
<customer>
<purchasedItems>
// add the xml here for the purchased Item chosen by id values
</purchasedItems>
</customer>
If customer purchased Item-1 and Item-3, then output will be:
<customer>
<purchasedItems>
<item>
<id>1</id>
<name>Item-1</name>
<price>10</price>
</item>
<item>
<id>3</id>
<name>Item-3</name>
<price>30</price>
</item>
</purchasedItems>
</customer>
i try with the following code which is not working :
<?php
header('Content-Type: text/xml');
class Items {
public static function addItem($purchasedItemsXml, $Items, $parentTag, $idTag ,$id)
{
$docSource = new DOMDocument();
$docSource->loadXML($Items);
$docDest = new DOMDocument();
$docDest->loadXML($purchasedItemsXml);
$xpath = new DOMXPath($docSource);
$result = $xpath->query("//{$idTag}[text()='{$id}']/parent::*");
$result = $docDest->importNode($result->item(0), true);
$items = $docDest->getElementsByTagName($parentTag)->item(0);
$items->appendChild($result);
echo $docDest->saveXML();
return ;
}
}
Updates: After changing Following code,Now Its Working Thanks to all.
class purchasedItems extends Items{
public static function addPurchasedItems($purchasedItemsXml, $Items, $parentTag, $idTag, $ids){
$count =0;
foreach ($ids as $id) {
if($count==0){
$xml = self::addItem($purchasedItemsXml, $Items, $parentTag, $idTag, $id);
}
else{
$xml = self::addItem($xml, $Items, $parentTag, $idTag, $id);
}
$count++;
}
echo $xml;
return ;
}
}
$Items = "<items>
<item>
<id>1</id>
<name>Item-1</name>
<price>10</price>
</item>
<item>
<id>2</id>
<name>Item-2</name>
<price>20</price>
</item>
<item>
<id>3</id>
<name>Item-3</name>
<price>30</price>
</item>
</items>";
$purchasedItemsXml = "<customer>
<purchasedItems>
</purchasedItems>
</customer>";
$ids = array(1, 3);
$parentTag = 'purchasedItems';
$idTag = 'id';
purchasedItems::addPurchasedItems($purchasedItemsXml, $Items, $parentTag, $idTag, $ids);
?>
as a beginner, i am sure i did some mistake, but i am now stuck at point.I want to do this using the existing given class hierarchy.please help me with this code.Thanks
You can achive this by using SimpleXML:
$xml = new SimpleXMLElement($purchasedItemsXml);
Then access like this: echo $xml->purchasedItems->item[0]->name;
To access children elements of a tag do this:
foreach($xml->purchasedItems->item as $item)
{
echo $item->name; //and other properties like this.
//if not sure try var_dump($item) here it will tell you.
}
Common mistake is to reference root element in your code, don't do that, or it won't work, you need to omit root element, in your case customer.
EDIT: To add items, find the items like I showed above, and add them like this:
$item = $xml->purchasedItems->addChild('item');
$item->addChild('name', 'SimpleXML Rocks just like that');
$item->addChild('id', '3');
echo $xml->saveXML();
Your “core” code is fine, but the classes construction is wrong (parent::addItem doesn't exist and addPayHead echoes one document for each added item).
This code — without classes — will work:
$ids = array(1, 3);
$parentTag = 'purchasedItems';
$idTag = 'id';
$docSource = new DOMDocument();
$docSource->loadXML($Items);
$docDest = new DOMDocument();
$docDest->loadXML($purchasedItemsXml);
$xpath = new DOMXPath($docSource);
foreach( $ids as $id )
{
$query = "//{$idTag}[text()='{$id}']/parent::*";
$result = $xpath->query( $query );
$result = $docDest->importNode($result->item(0), true);
$items = $docDest->getElementsByTagName($parentTag)->item(0);
$items->appendChild($result);
}
echo $docDest->saveXML();
I'm using this code to dynamically update an xml file,
my problem is that I'm confused about how to apply the order of the actions to do:
<?php
$files = scandir('./resources');
sort($files);
foreach($files as $file){
if(is_dir("./resources/$file") and $file != "." && $file != ".."){
myFun($file);
}
}
$simplexml = simplexml_load_file('map.xml');
function myFun($scannedTitle){
$tags = get_meta_tags('./resources/'.$scannedTitle.'/index.html');
$scannedDescription = $tags['description'];
$items = $simplexml->xpath('channel/item[#id="'.$scannedTitle.'"]');
$items = $items[0];
if($items->title[0] == $scannedTitle){
}else{
$items->title[0] = $scannedTitle;
}
if($items->description[0] == $scannedDescription){
}else{
$items->description[0] = $scannedDescription;
}
}
$simplexml->saveXML("map.xml");
?>
The code was working, but now I changed the order of the functions and it does no longer work..
I can't understand in which order I have to perform the actions...
Here my "map.xml" file:
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<item id="red">
<title>red</title>
<link>http://website.com/resources/red/</link>
<description>descriptionRed</description>
</item>
<item id="green">
<title>green</title>
<link>http://website.com/resources/green/</link>
<description>Description of the green page.</description>
</item>
<item id="blue">
<title>blue</title>
<link>http://website.com/resources/blue/</link>
<description>Description of the blue page.</description>
</item>
</channel>
</rss>
You have a variable scoping issue how myFun() is going to process $simplexml which is created outside the function.
i think that it will work this way by passing a reference for $simplexml in the function
<?php
$simplexml = simplexml_load_file('map.xml');
$files = scandir('./resources');
sort($files);
foreach($files as $file){
if(is_dir("./resources/$file") and $file != "." && $file != ".."){
myFun($file, $simplexml);
}
}
function myFun($scannedTitle, &$simplexml){
$tags = get_meta_tags('./resources/'.$scannedTitle.'/index.html');
$scannedDescription = $tags['description'];
$items = $simplexml->xpath('channel/item[#id="'.$scannedTitle.'"]');
$items = $items[0];
if($items->title[0] == $scannedTitle){
}else{
$items->title[0] = $scannedTitle;
}
if($items->description[0] == $scannedDescription){
}else{
$items->description[0] = $scannedDescription;
}
}
$simplexml->saveXML("map.xml");
?>
I am trying to edit some XML with PHP. Currently the XML looking something like:
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Main Title</title>
<link>http://exmaple.com</link>
<description> blahblahblah </description>
<language>en</language>
<item>
<title>Tite1</title>
<link>http://www.example.com (THIS IS WHAT I WANT)</link>
<description>blah blah blah</description>
</item>
.
.
.
</channel>
</rss>
I've tried to access the 2nd level link but my code only changes the first Link node value. Here is the code:
$xml->load('http://www.google.com/doodles/doodles.xml');
$element = $xml->getElementsByTagName('channel')->item(0);
$secondlvl = $element->getElementsByTagName('item')->item(0);
$2ndlevellinknode = $element->getElementsByTagName('link')->item(0);
$2ndlevellinknode->nodeValue = $newvalue;
Any suggestions? Also is it possible to use this line of code in a for loop like this
for ($i = 0; $i <= 20; $i++) {
$element = $xml->getElementsByTagName('channel')->item(0);
$secondlvl = $element->getElementsByTagName('item')->item(0);
$2ndlevellinknode = $element->getElementsByTagName('link')->item($i);
$2ndlevellinknode->nodeValue = $newvalue;
}
this should give you an idea.
$f = simplexml_load_file('test.xml');
print $f->channel->title . "\n";
print $f->channel->link . "\n";
print $f->channel->description . "\n";
foreach($f->channel->item as $item) {
print $item->title . "\n";
}