Place a while loop in a string - php

I would like to create a function where users can create there own XML feed. The feed should be for example the following (quite simple example) feed:
<xml>
<products>
<product>Product 1</product>
<product>Product 2</product>
</products>
</xml>
Very important in the setup is that there is a connection between the database and the setup feed, for example the is loaded from the database. So, the user should create for example the following 'text/xml' as basis:
<xml>
<products>
%whileProducts%
<product>%title%</product>
%/whileProducts%
</products>
</xml>
It is possible to enter the product title via a str_replace, but is it also possible to create a while loop via a replace function? To make it a bit more difficult: it could be possible that there are multiple loops in a loop, for example, a user would like to create a feed with a while loop for the products and inside this loop a new loop for the colors and/or sizes of the product.

No, it's not. str_replace() can only perform literal replacements of one set of constant strings with another corresponding set of constant strings; it can't do anything more complex.
What you want here is a templating engine. Since XML is involved, XSLT may be an appropriate tool to use; it's not simple, though. There are many other templating engines for PHP available, and recommending one is outside the scope of this question.

Related

Map XML accordingly

I am having trouble finding a solution to a problem I am facing, parsing XMLs.
Let me describe what I have now and what's the issue:
I have LINKs of XMLs files that have for example:
<prodcuts>
..
<product>
<id>1</id>
<name><![CDATA[ this is a test product name ]]></name>
<link><![CDATA[http://www.google.com]]></link>
<image><![CDATA[http://www.google.com/image.jpg]]></image>
<sku><![CDATA[ ]]></sku>
<category><![CDATA[ System > Technology ]]></category>
<price>20</price>
<description><![CDATA[ ]]></description>
<instock><![CDATA[ Y ]]></instock>
<availability>Y</availability>
</product>
..
</products>
Another XML has:
<prodcuts>
..
<product>
<productID>1</productID>
<title><![CDATA[ ]]></title>
<link><![CDATA[http://www.google.com]]></link>
<image><![CDATA[http://www.google.com/image.jpg]]></image>
<sku><![CDATA[ ]]></sku>
<categoryPath><![CDATA[ System > Technology ]]></categoryPath>
<price>20</price>
<description><![CDATA[ ]]></description>
<instock><![CDATA[ Y ]]></instock>
<availability>Y</availability>
<size>40</size>
</product>
..
</products>
Now, the difference between those are
1) the first one has a tag name "name", the other one has a tag name "title".
2) The second one has some tags that the first one does not.
Now the problem is, I am parsing the XML file via PHP like this:
$xml->products->product[$i]->id
$xml->products->product[$i]->name
and so on.. If I do this the code I have wrote, will work only for the first one. The tags that are missing is not a problem for now, cause I am inserting to Database NULL cause there are not required fields..
But, what about the second XML? Can I do something "automatically" in order to avoid asking to correct those tags?
This could be done only manually, by grabbing the content of this LINK (via PHP) and rename those ones?
I do not have the file from my clients, just the LINK of XML.
thanks in advance!
ok! I believe I have found some solutions to my problem.. I wrote them here in case someone has the same issues:
Solutions:
i) Read all the children of XML file, no matter how they are written (case-sensitive) and add them to Database. After that, there is a dashboard/PHP file with SQL queries that MATCH those children elements tags of XML with the one that you want.
In this case, you may want to create a file called whatever you like, for example test.xml and CREATE the one that you want, with the correct XML tag elements. In this case, you could UPDATE this, every some hour (according to your needs) via a cronjob..
ii) Create manually the PHP file with the parsing inside, for every XML that you get. Just make sure to keep the XML link in your DB
iii) Ask the client to give you the correct XML. XML is case-sensitive for a reason.
In case you choose the first solution you need to make changes to php.ini file too, cause the XML files may be too large and the max_execution_time is probably too low to run all these PHP - MySQL scripts.
if someone need more explain or have any better advice, please share!

PHP use XML file as a data repository

I have a simple PHP application, which uses MySQL DB, but I think that maybe the using of DB is needlessly for such easy operations.
Anyway, I hove some problems with the XML operations.
Let's say I want to have XML structure like this:
<root>
<experiment>
<name>test</name>
<accessCount>5</accessCount>
<downloadEntry>
<date>2015-11-27</date>
<comment>comment</comment>
</downloadEntry>
<downloadEntry>
<date>2015-11-28</date>
<comment>comment</comment>
</downloadEntry>
</experiment>
</root>
Now I would like to know, how to do these operations:
Count download entries (count of downloadEntry nodes) of experiment with name "test". Via XPATH?
Get download entries of experimetn with name test - but I would like to have pagination on this. So get download entries somehow like LIMIT 0,5.
The biggest problem is that, when there are no experiments - so the XML is , the loading of XML with simplexml_load_file fails. I can't open it. Yes, I can add the condition - if the XML is empty, donť open it. But I need to write to it and can't write if it isnť open.
Is there a solution for that?
Thanks everyone

PHP - Append and update large XML files

I'm looking into the possibility of efficiently comparing two similar XML-files and updating outdated information.
The main XML-file I'm working with is about 200-250mb in size. The second is a tad smaller.
The two XML-files pretty much looks like this:
<product>
<Category>BOOK</Category>
<Bookgroup>BOOKF</Bookgroup>
<Productname>Name of the book</Productname>
<Productcode>123456789</Productcode>
<Price>79.00</Price>
<Availability>Stock On Order</Availability>
<ProductURL>www.url.com</ProductURL>
<Release>07.08.2013</Release>
<Author>Name of author</Author>
<Genre>Crime</Genre>
<BookType>Pocket</BookType>
<Language>English</Language>
</product>
As you can see I'm working with books, and the purpose of having a second XML-file with the same information is that I only want one copy of each book for further use.
Basically I'm trying to figure out how I effectively can parse through the first XML and check whether the book exists in the second XML. If it exists I'll check if productinformation (price, availabilty etc) have been updated. If this information has been updated this needs to be updated in the second XML as well.
If it doesnt exist it needs to be added to the second XML.
Using XMLReader I'm able to parse through each book from the first XML fairly fast (40ish seconds to loop through 4,5million lines of XML and echo out all the books) by using a similar approach as this.
My problem occurs when I want to check if this book exists in the second XML and make changes in the second XML if it needs to be updated or added.
Would it for example be possible to use XMLReader on the second XML and stop at nodes with the same booktitle as I've stopped at in the first XML and then make the check? If so how?

Editing and deleting XML nodes with PHP

I've been looking around but still can't find a workable answer to editing and deleting xml with php without the use of simpleXML (how I wish i could use it). I was hoping someone could break it down simply for me, as my brain doesn't cope with this stuff! The xml file I have to work with looks something like this:
<allentries>
<entry>
<entryid>1</entryid>
<title>This is the title</title>
<date>2010</date>
<author>Some Guy</author>
</entry>
<entry>
<entryid>2</entryid>
<title>This is Another title</title>
<date>2011</date>
<author>Some Other Guy</author>
</entry>
<entry>
<entryid>3</entryid>
<title>This is the other title</title>
<date>2012</date>
<author>And Another Guy</author>
</entry>
</allentries>
I need to be able to do two things with PHP - Firstly I need to be able to accept values posted from a form, pick the correct entry based on the entryid number and modify each element within that entry with the new data. For eg. if entryid = 2, skip to the second entry and replace the text within title, date and author with the new data.
The second thing I need to be able to do (with a different function obviously) is pick the entry based on the entryid number and delete the whole entry, tag, data, children and all.
It sounds like it shouldn't be too hard, but every example I've used so far fails to do anything. Can anybody suggest anything or any other tutorials somewhere that may help me?
Thanks muchly for your time!
2 quick ways, both using regular expressions:
break the XML to array using regular expressions, with the value of the entryid as key
on update just construct the new value and replace the value at the specified key
on delete just unset
use regular expression to replace nodes
No idea on the performance for this two cases. I'll try and provide an regular expression to help you.
Gabriel
Ok, sorry, did some further research and found a good example at this site using:
$xml_file = "thefile.xml";
if(!$xml=simplexml_load_file($xml_file)){
trigger_error('Error reading XML file',E_USER_ERROR);
}
simplexml_load_file instead of simplexml_load_string works like a charm now! No wonder you guys were confused - thanks for all your replies and for tolerating my noobishness!

How to parse an XML tree with DOMDocument?

Here is my XML file :
<?xml version="1.0" encoding="utf-8"?>
<root>
<category>
<name>Category</name>
<desc>Category</desc>
<category>
<name>Subcategory</name>
<desc>Sub-category</desc>
<category>
<name>Subcategory</name>
<desc>Sub-category</desc>
</category>
</category>
</category>
</root>
My tree could have as much levels as possible. There are no requirements about this.
First question :
Is my XML correct to handle this kind of requirement ?
and How could i optimize it (if it's needed)
Second question :
How could I parse it with DOMDocument ?
I know how to load an xml document, but I don't know how to parse it.
I read a little on recursion but I was not able to understand properly how to map with PHP/DOMDocument.
Thanks for the help !
EDIT
What I want to do is manage a category system.
I tried with SQL but it was too hard to manage using the relational model, even with nested select, etc...
So i want to be able make a tree from my xml
like
Category
Sub Category
Sub sub category
Without limits on the depth
I want to be able to search for a category, retrieve all its children (subcategories) (or not), its parent(s) (or not), (the sisters ?), etc...
Well, there's nothing wrong with the XML you're using here, but you don't say enough about what you want to DO with the data for anyone to give you a quality answer about whether or not your XML will capture what you need. As for "[parsing] it with DOMDocument", you can load it into a DOMDocument object like so:
$xml = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<root>
<category>
<name>Category</name>
<desc>Category</desc>
<category>
<name>Subcategory</name>
<desc>Sub-category</desc>
<category>
<name>Subcategory</name>
<desc>Sub-category</desc>
</category>
</category>
</category>
</root>
XML;
$d = new DOMDocument();
$d->loadXML($xml);
At this point, the question once again becomes: Now what do you want to DO with it?
If you're just talking about how to handle a structure like this - i'd say write two functions, one that accepts the full structure, and one that accepts a category DOMNode reference. The first function would do initial processing then pass the first reference to the initial Category node. Then in this function, you process the current node's properties as needed, and then recurse into children if they are present.
It would be more efficient to process this flat of course, in one loop, but then you would lose the literal representation of the hierarchy.
Recapping the point above about what you want to do with it... IMHO there are three broad classes of thing one might do with a chunk of XML.
Having instantiated a DOMDocument and loaded XML into it, you can search it for nodes using XPath queries, much like you search a relational database using SQL SELECT queries. You can extract properties of node, sub-nodes of nodes and the text within nodes. Which is a species of parsing, I'd say. DOMDocument XPath component will do this for you.
You can instead maybe turn your XML into something else - different XML dialect, XHTML, etc, using XSL Transforms. Which may or may not be parsing per se, but does involve parsing. PHP XSLTProcessor component will do this.
Another major idea, which I think DOMDocument does not really support, is a streaming parser. The parser consumes XML in a linear manner, and while doing so invokes callback functions at each node of interest. The somewhat venerable parser named SAX is AFAIK the archetypal streaming parser. There used to be a SAX parser in PHP, I think it has now been moved to PEAR or PECL.
But, yeah, what do you want to do with your XML?
You said you tried SQL and it didn't work for you. Just a tip: If you use Oracle, take a look at START WITH ... CONNECT BY, if you use SQL Server, use recursive CTEs. These approaches do solve the problem.

Categories