Same variable from multiple XML - php

$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.

Related

SimpleXML returns combined XML content

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;
}

How to add spaces between values in xml?

I have to create an xml out of other xml. I already have the answer to that, but then I'm facing another problem. The output of the xml is quite messy in the tag.
The xml is this:
<rss>
<item id="12907">
<g:productname>Black Bag</g:productname>
<g:detailed_images>
<g:detailed_image>Image1.jpg</g:detailed_image>
<g:detailed_image>Image2.jpg</g:detailed_image>
<g:detailed_image>Image3.jpg</g:detailed_image>
<g:detailed_image>Image4.jpg</g:detailed_image>
<g:detailed_image>Image5.jpg</g:detailed_image>
<g:detailed_image>Image6.jpg</g:detailed_image>
<g:detailed_image>Image7.jpg</g:detailed_image>
<g:detailed_image>Image8.jpg</g:detailed_image>
<g:detailed_image>Image9.jpg</g:detailed_image>
<g:detailed_image>Image10.jpg</g:detailed_image>
<g:detailed_image>Image11.jpg</g:detailed_image>
<g:detailed_image>Image12.jpg</g:detailed_image>
</g:detailed_images>
</item>
<item id="12906">
<g:productname>Yellow Bag</g:productname>
<g:detailed_images>
<g:detailed_image>Image1.jpg</g:detailed_image>
<g:detailed_image>Image2.jpg</g:detailed_image>
<g:detailed_image>Image3.jpg</g:detailed_image>
<g:detailed_image>Image4.jpg</g:detailed_image>
<g:detailed_image>Image5.jpg</g:detailed_image>
<g:detailed_image>Image6.jpg</g:detailed_image>
<g:detailed_image>Image7.jpg</g:detailed_image>
<g:detailed_image>Image8.jpg</g:detailed_image>
<g:detailed_image>Image9.jpg</g:detailed_image>
<g:detailed_image>Image10.jpg</g:detailed_image>
<g:detailed_image>Image11.jpg</g:detailed_image>
<g:detailed_image>Image12.jpg</g:detailed_image>
</g:detailed_images>
</item>
</rss>
The php code that I'm using to create another xml file is this
<?php
$document = new DOMDocument;
$document->formatOutput = true;
$document->preserveWhiteSpace = false;
$document->load('xml_feeds.xml');
$xpath = new DOMXPath($document);
$fields = [
'productname' => 'string(g:productname)',
'detailed_images' => 'string(g:detailed_images)'
];
$xml = new DOMDocument;
$xml->formatOutput = true;
$xml->preserveWhiteSpace = false;
$rss = $xml->appendChild($xml->createElement('rss'));
foreach ($xpath->evaluate('//item') as $item) {
//create tag item
$createItem = $rss->appendChild($xml->createElement('item'));
//getting item's attribute value
$valueID = $item->getAttribute('id');
//create attribute
$itemAttribute = $xml->createAttribute('id');
$itemAttribute->value = $valueID;
$createItem->appendChild($itemAttribute);
foreach ($fields as $caption => $expression) {
$value = $xpath->evaluate($expression, $item);
$createItem->appendChild($xml->createElement($caption, $value));
}
}
$xml->save('new_createxml2.xml');
?>
The result of the new_createxml2.xml is this
<?xml version="1.0"?>
<rss>
<item id="12907">
<productname>Black Bag</productname>
<detailed_images>Image1.jpgImage2.jpgImage3.jpgImage4.jpgImage3.jpgImage4.jpgImage5.jpgImage6.jpgImage7.jpgImage8.jpgImage9.jpgImage10.jpgImage11.jpgImage12.jpg</detailed_images>
</item>
<item id="12906">
<productname>Yellow Bag</productname>
<detailed_images>Image1.jpgImage2.jpgImage3.jpgImage4.jpgImage3.jpgImage4.jpgImage5.jpgImage6.jpgImage7.jpgImage8.jpgImage9.jpgImage10.jpgImage11.jpgImage12.jpg</detailed_images>
</item>
</rss>
I really wonder how can I create the xml tidier than what I've made. I want it to display like this actually:
<?xml version="1.0"?>
<rss>
<item id="12907">
<productname>Black Bag</productname>
<detailed_images>Image1.jpg, Image2.jpg, Image3.jpg, Image4.jpg, Image3.jpg, Image4.jpg, Image5.jpg, Image6.jpg, Image7.jpg, Image8.jpg, Image9.jpg, Image10.jpg, Image11.jpg, Image12.jpg</detailed_images>
</item>
<item id="12906">
<productname>Yellow Bag</productname>
<detailed_images>Image1.jpg, Image2.jpg, Image3.jpg, Image4.jpg, Image3.jpg, Image4.jpg, Image5.jpg, Image6.jpg, Image7.jpg, Image8.jpg, Image9.jpg, Image10.jpg, Image11.jpg, Image12.jpg</detailed_images>
</item>
</rss>
Thank you for your help
The way you've tried it is quite simple for some things, but as you've found out that this method fails when you want processing for each individual piece of data. When you use 'string(g:detailed_images)' - this is the text content of all of the subnodes in your document, which is why you have all of the values stuck together. You could then process this string with some form of regular expression - but as you have no control of the content it's difficult to know what you are going to find.
Changing it to a more traditional - get values using a specific XPath call and processing the values allows you more control over the result.
foreach ($xpath->evaluate('//item') as $item) {
//create tag item
$createItem = $rss->appendChild($xml->createElement('item'));
//getting item's attribute value
$valueID = $item->getAttribute('id');
//create attribute
$itemAttribute = $xml->createAttribute('id');
$itemAttribute->value = $valueID;
$createItem->appendChild($itemAttribute);
$prodName = $xpath->evaluate("string(g:productname)", $item);
$createItem->appendChild($xml->createElement('productname', $prodName));
$images = [];
foreach ( $xpath->query("descendant::g:detailed_image", $item) as $image ) {
$images[] = $image->nodeValue;
}
$createItem->appendChild($xml->createElement('detailed_images',
implode(",", $images)));
}

How to get 2 child ID value from XML?

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);

How to correct this code for adding selected xml tags from one xml source into another using xpath and php class methods

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();

Removing an element form XML file in PHP

i tried to find it out with previous answers but i cannot do it propperly, i followed Stefan's answer Remove a child with a specific attribute, in SimpleXML for PHP
and my code is
xml:
<?xml version="1.0" encoding="utf-8"?>
<res>
<items>
<item>
<id>1</id>
<a>asdasda</a>
</item>
<item>
<id>1</id>
<a>bababba</a>
</item>
<id>2</id>
<a>sasdasda</a>
</item>
<item>
<id>3</id>
<a>sasdasda</a>
</item>
<item>
<id>4</id>
<a>sasdasda</a>
</item>
<item>
<id>5</id>
<a>sasdasda</a>
</item>
<item>
<id>6</id>
<a>sasdasda</a>
</item>
</items>
</res>
and php is
<?php
$id="1";
$xml = simplexml_load_file("filtracjaxml.xml") ;
foreach($xml->items->item->id as $id)
{
if($id == '1') {
$xml=dom_import_simplexml($id);
$xml->parentNode->removeChild($xml);
}
}
echo $xml->asXml();
?>
when i try to run it i have
Fatal error: Call to undefined method DOMElement::asXml() in filtruj.php on line 14
EDIT:
What I want is deleting the whole 'item' not only 'id' - all items with id = 1
so i changed the code :
foreach ( $xml->items->item as $id )
{
if ( $id->id == '1' ) {
$tmp = dom_import_simplexml($id);
$tmp->parentNode->removeChild($tmp);
}
}
echo $xml->asXml();
and it deletes only the first item. Could you tell me why? what is wrong in the code written above?
<?php
$id="1";
$xml = simplexml_load_file("filtracjaxml.xml") ;
foreach ( $xml->items->item->id as $id )
{
if ( $id == '1' ) {
$tmp = dom_import_simplexml($id);
$tmp->parentNode->removeChild($tmp);
}
}
echo $xml->asXml();
?>

Categories