I have a XML file with following schema:
<?xml version="1.0" encoding="UTF-8"?>
<languages>
<language type="persian" abbr_type="fa">
<menu>
<home></home>
<contact></contact>
<about></about>
<style></style>
</menu>
<title>
<home></home>
<contact></contact>
<about></about>
<style></style>
<list></list>
<biography></biography>
<picture></picture>
<movie></movie>
</title>
<about></about>
<welcome></welcome>
</language>
<language type="english" abbr_type="en">
<menu>
<home></home>
<contact></contact>
<about></about>
<style></style>
</menu>
<title>
<home></home>
<contact></contact>
<about></about>
<style></style>
<list></list>
<biography></biography>
<picture></picture>
<movie></movie>
</title>
<about></about>
<welcome></welcome>
</language>
I wanna get Title data if attribute of language tag is "persian".
How can I get a series of data from XML, exactly? Is there any way to get data and put in an array?
Is there any way to get data and put in an array?
Yes, you can use DOMDocument > http://php.net/manual/en/class.domdocument.php . It create tree like structure in which you can easily find what are you looking for.
EXAMPLE
$xml = new DOMDocument();
$xml->loadXML($xmlString);
$xmlNodeArray = $xml->getElementsByTagName('language');
foreach ($xmlNodeArray as $element) {
if($element->getAttribute('type') == "persian") {
// do something with that element
}
}
Related
I load the following XML data into SimpleXML like this:
<?php
$xmlString = <<<'XML'
<?xml version="1.0"?>
<response>
<item key="0">
<title>AH 2308</title>
<field_a>3.00</field_a>
<field_b>7.00</field_b>
<field_d1>35.00</field_d1>
<field_d2>40.00</field_d2>
<field_e></field_e>
<field_g2></field_g2>
<field_g>M 45x1,5</field_g>
<field_gewicht>0.13</field_gewicht>
<field_gtin>4055953012781</field_gtin>
<field_l>40.00</field_l>
<field_t></field_t>
<field_abdrueckmutter>KM 9</field_abdrueckmutter>
<field_sicherung>MB 7</field_sicherung>
<field_wellenmutter>KM 7</field_wellenmutter>
</item>
<item key="1">
<title></title>
<field_a></field_a>
<field_b></field_b>
<field_d1></field_d1>
<field_d2></field_d2>
<field_e></field_e>
<field_g2></field_g2>
<field_g></field_g>
<field_gewicht></field_gewicht>
<field_gtin></field_gtin>
<field_l></field_l>
<field_t></field_t>
<field_abdrueckmutter></field_abdrueckmutter>
<field_sicherung></field_sicherung>
<field_wellenmutter></field_wellenmutter>
</item>
</response>
XML;
$xml = simplexml_load_string($xml);
How can I achieve the following result:
<?xml version="1.0"?>
<response>
<item key="0">
<title>AH 2308</title>
<field_a>3.00</field_a>
<field_b>7.00</field_b>
<field_d1>35.00</field_d1>
<field_d2>40.00</field_d2>
<field_e></field_e>
<field_g2></field_g2>
<field_g>M 45x1,5</field_g>
<field_gewicht>0.13</field_gewicht>
<field_gtin>4055953012781</field_gtin>
<field_l>40.00</field_l>
<field_t></field_t>
<field_abdrueckmutter>KM 9</field_abdrueckmutter>
<field_sicherung>MB 7</field_sicherung>
<field_wellenmutter>KM 7</field_wellenmutter>
</item>
<item key="1"></item>
</response>
To delete all empty elements, I could use the following working code:
foreach ($xml->xpath('/child::*//*[not(*) and not(text()[normalize-space()])]') as $emptyElement) {
unset($emptyElement[0]);
}
But that's not exactly what I want.
Basically, when the <title> element is empty, I want to remove it with all its siblings and keep the parent <item> element.
What's important: I also want to keep empty element, if the <title> is not empty. See <item key="0"> for example. The elements <field_e>, <field_g2> and <field_t>will be left untouched.
Is there an easy xpath query which can achieve that? Hope anyone can help. Thanks in advance!
This xpath query is working:
foreach ($xml->xpath('//title[not(text()[normalize-space()])]/following-sibling::*') as $emptyElement) {
unset($emptyElement[0]);
}
It keeps the <title> element but I can live with that.
DOM is more flexible manipulating nodes:
$document = new DOMDocument();
$document->loadXML($xmlString);
$xpath = new DOMXpath($document);
$expression = '/response/item[not(title[normalize-space()])]';
foreach ($xpath->evaluate($expression) as $emptyItem) {
// replace children with an empty text node
$emptyItem->textContent = '';
}
echo $document->saveXML();
I have a php code that use to parse xml data, but it is not working, my php code look as following:
<?php
$xml = '<?xml version="1.0" encoding="utf-8"?>
<videos>
<video>
<id>751985</id>
<embed><![CDATA[somehtmlcode]]></embed>
<thumbs>
<thumb><![CDATA[http://example.com/images/thum01.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum02.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum03.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum04.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum05.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum06.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum07.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum08.jpg></thumb>
</thumbs>
<link><![CDATA[http://example.com/001]]></link>
<title><![CDATA[Some cool title 1]]></title>
<categories>
<category><![CDATA[Cat1]]></category>
<category><![CDATA[Cat2]]></category>
<category><![CDATA[Cat3]]></category>
<category><![CDATA[Cat4]]></category>
</categories>
<tags>
<tag><![CDATA[tag1]></tag>
<tag><![CDATA[tag2]></tag>
<tag><![CDATA[tag3]></tag>
</tags>
<someone>
</someone>
<duration><![CDATA[8:17]]></duration>
<pubDate><![CDATA[2014-05-14]]></pubDate>
</video>
<video>
<id>751988</id>
<embed><![CDATA[somehtmlcode]]></embed>
<thumbs>
<thumb><![CDATA[http://example.com/images/thum01.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum02.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum03.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum04.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum05.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum06.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum07.jpg></thumb>
<thumb><![CDATA[http://example.com/images/thum08.jpg></thumb>
</thumbs>
<link><![CDATA[http://example.com/001]]></link>
<title><![CDATA[Some cool title 1]]></title>
<categories>
<category><![CDATA[Cat1]]></category>
<category><![CDATA[Cat2]]></category>
<category><![CDATA[Cat3]]></category>
<category><![CDATA[Cat4]]></category>
</categories>
<tags>
<tag><![CDATA[tag1]></tag>
<tag><![CDATA[tag2]></tag>
<tag><![CDATA[tag3]></tag>
</tags>
<someone>
</someone>
<duration><![CDATA[8:17]]></duration>
<pubDate><![CDATA[2014-05-14]]></pubDate>
</video>
</videos>';
$sxe = simplexml_load_string($xml);
foreach ($sxe->video as $videoChild) {
echo $videoChild->id;
echo $videoChild->title;
}
?>
it does not get the value of node, i need to get id, embed, thumb, link, title, without the CDATA tag. any help would be great.
<thumb><![CDATA[http://example.com/images/thum01.jpg></thumb>
the [CDATA] things aren't closed properly, simplexml_load_string() doesn't like that
try
<thumb><![CDATA[http://example.com/images/thum01.jpg]]></thumb>
I've made a simple news script that saves articles to rss which then gets used on the Character Generator Newsticker on TV, the problem is that the CG plays the nodes starting from the top of the rss file.
now the xml looks like this:
<?xml version="1.0" ?>
<rss version="2.0">
<channel>
<title>News</title>
<link>website.com</link>
<description>News</description>
<language>ar-sa</language>
<item>
<title>Headline 1</title>
<description>Headline one the news this hour</description>
</item>
<item>
<title>Headline 2</title>
<description>Fire here flooding over there</description>
</item>
<item>
<title>Headline 3</title>
<description>Fire here flooding over there</description>
</item>
</channel>
</rss>
What i would like todo is have an option to move articles up and down the xml file, so instead of having "Headline 3" third in the list i would like to move it up to be first.
I know with C# you can do this using:
XElement node = ...get the element...
//Move up
if (node.PreviousNode != null) {
node.PreviousNode.AddBeforeSelf(node);
node.Remove();
}
//Move down
if (node.NextNode != null) {
node.NextNode.AddAfterSelf(node);
node.Remove();
Anyone have an idea how i can do this in PHP?
Thanks!
You can have a look at this answer XML reforming with DOM where they use the DOM-parser to rearrange the XML
I am very new to Zend Framework. And i have tried to get the XML value but cant make it work.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<result count="2">
<blocks>
<listing>
<title>Title 1</title>
<id>1</id>
</listing>
<listing>
<title>Title 2</title>
<id>2</id>
</listing>
</blocks>
</result>
PHP (to find all the title):
$dom = new Zend_Dom_Query();
$dom->setDocumentXml($result);
$results = $dom->queryXpath('/result/blocks/listing/title');
//$dom->queryXpath('/*/*/listing'); no luck
//$dom->queryXpath('///listing'); no luck
foreach($results as $k)
{
Zend_Debug::dump($k->getAttribute('title')); // empty
echo $k->getDocument(); // shows none
}
Any help?
Using queryXpath('/result/blocks/listing/title') your $k already is the DOMElement that represents the <tile>...</title> elements.
You can retrieve the value via $k->nodeValue. For a DOMElement that's the concatenation of all text nodes in the descendant axis.
foreach($results as $k)
{
Zend_Debug::dump($k->nodeValue); // empty
}
title is a node - not an attribute - attributes are placed inside the tag :)
i'm trying to pass an xml node to a function but can't figure out how - here's my xml markup:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<root>
<form>
<item>
<id>frm1</id>
<dbID>1</dbID>
<visible>1</visible>
</item>
</form>
<form>
<item>
<id>frm2</id>
<dbID>2</dbID>
<visible>1</visible>
</item>
</form>
</root>
when setting up a foreach loop - how's the syntax to iterate through the xml and passing the whole node to a function?
i've tried something like:
foreach($xml as $ctlXML => $value)
{
$ctl = generateCTL($ctlXML);
}
but it doesn't work as it should.
thanks
If you are using SimpleXML it is simple as
$xml = simplexml_load_file($path_to_file);
foreach($xml->form as $form){
$ctl = generateCTL($form->item);
}
Be careful - $form->item is an object