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");
?>
Related
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;
}
$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 have a XML document:
<product>
<item>
<item00>
<name>DVD</name>
</item00>
</item>
</product>
<product>
<item>
<item11>
<name>CD</name>
</item11>
</item>
</product>
And I would like to show the names of these products, but there are products with item as "item00" and "item11".
I tried adding the path regular expressions in XPath, but without success.
There is a possibility I display the name of these products (DVD and CD) using XPath?
<?php
$xml = 'file.xml';
$content = '';
$f = fopen($xml, 'r');
while($data = fread($f, filesize($xml))) {
$content.= $data;
}
fclose($f);
preg_match_all('/\<product\>(.*?)\<\/product\>/s', $content, $product);
$product = $product[1];
$doc = new SimpleXMLElement($content);
for($i = 0; $i <= count($product) - 1; $i++) {
// So far, no problems. Seriously.
// The issue starts here.
$query = $doc->xpath('/product/item/???');
foreach($query as $item) {
echo $item->name . '<br>';
}
}
?>
Where "???" is the problem with "item00" and "item11".
If anyone knows and can help me, I'll be very grateful!
Here is the total working code
<?php
$xml = 'file.xml';
$content = '';
$f = fopen($xml, 'r');
while($data = fread($f, filesize($xml))) {
$content.= $data;
}
fclose($f);
$content = "<root>$conten</root>";
$doc = new SimpleXmlElement($content);
$query = $doc->xpath('//item/child::*');
foreach($query as $item) {
echo $item->name . '<br>';
}
i dont think you can use regex in that context, that's the very reason to use attributes
<item num="00">
however check this, i believe it is what you are looking for
those 00 11 things really should be attributes
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 xml file such as this:
<?xml version="1.0"?>
<datas>
<books>
<book>
<id>1</id>
<title>PHP Undercover</title>
<author>Wiwit Siswoutomo</author>
</book>`enter code here`
<book>
<id>2</id>
<title>PHP Enterprise</title>
<author>Wiwit Siswoutomo</author>
</book>
</books>
</datas>
and now i wana to replace a special tag in this way:
search in xml file and if it has a PHP Enterprise ,find it and replace it by 'new title'.
What should i do?
TNX
You can parse the document with SimpleXML:
$datas = new SimpleXMLElement("my.xml");
foreach ($datas->books->book as $book) {
if (preg_match('/PHP Enterprise/', $book->title) {
$book->title = "new title";
}
}
$datas->asXML("my.xml");
This script will help you!! Try this :)
<?php
function replace_Special_Str($mystring)
{
//Load file
$filename="./myfile.xml";
if (!file_exists($filename)) { echo "There is not a myfile.xml file in the directory."; exit;}
$xml = simplexml_load_file($filename);
//search and replace particular node by book title
$node = $xml->xpath('/datas/books[title="' . $mystring. '"]');
if(sizeof($node) > 0)
{
$node[0]->title = 'My Title';
}
$xml->asXML('./aucstatus.xml');
}
?>
OR Try This,
<users>
<name>John</name>
<address>My Address</address>
<zipcode>12345</zipcode>
<city>My City</city>
<phone>555 1234-4321</phone>
</users>
PHP FILE
fopen('users.xml');
while ($users->read()) {
switch ($users->nodeType) {
case (XMLReader::ELEMENT):
if ($users->localName == "users") {
$node = $reader->expand();
$dom = new DomDocument();
$n = $dom->importNode($node,true);
$dom->appendChild($n);
$simple_xml = simplexml_import_dom($n);
$id = $simple_xml['id'];
$name = $simple_xml->name;
$address = $simple_xml->address;
// Custom code insert, update, whatever...
}
}
}