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
Related
Here is the XML that I am working on :
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:noo="http://www.myscheme.com/schema">
<channel>
<item>
<title>A Simple Title</title>
<noo:subcategory>the sub category</noo:subcategory>
<noo:relatedInfos>
<noo:teams>
<noo:team id="3">New York</noo:team>
<noo:team id="4">Las Vegas</noo:team>
</noo:teams>
</noo:relatedInfos>
</item>
</channel>
</rss>
I am doing this php code to get the two "team" but it does not work ($xml has the previous content) :
$xml_datas = simplexml_load_string($xml);
foreach($xml_datas->channel->item as $item){
$noo = $item->children('noo');
echo $noo->team;
}
Do you have any idea why it is not working ?
Thanks
See if this helps:
<?php // RAY_temp_userco.php
error_reporting(E_ALL);
$xml = <<<ENDXML
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:noo="http://www.myscheme.com/schema">
<channel>
<item>
<title>A Simple Title</title>
<noo:subcategory>the sub category</noo:subcategory>
<noo:relatedInfos>
<noo:teams>
<noo:team id="3">New York</noo:team>
<noo:team id="4">Las Vegas</noo:team>
</noo:teams>
</noo:relatedInfos>
</item>
</channel>
</rss>
ENDXML;
$obj = simplexml_load_string($xml);
$ns = $obj->getNamespaces(TRUE);
foreach($obj->channel->item as $item){
$noo = $item->children($ns['noo']);
var_dump($noo);
}
"noo" is just a local alias for that namespace, and the ->children() method (and most XML handling functions) want to know its actual global identifier, which is the URI in the xmlns attribute.
You need to either specify the full identifier of the namespace (i.e. ->children('http://www.myscheme.com/schema')) or set the optional second parameter to tell SimpleXML to look up the prefix (->children('noo', true). The second may be more readable, but it will break if a future document has the same schema, but gives the namespace a different local alias.
Additionally, the team nodes aren't directly under the item node, so you need to traverse further to get them:
// Give the namespace a readable name that won't change
define('NS_NOO', 'http://www.myscheme.com/schema');
$xml_datas = simplexml_load_string($xml);
foreach($xml_datas->channel->item as $item){
$teams = $item->children(NS_NOO)->relatedInfo->teams;
echo $teams->team[0];
}
I have a simple well-formed XML doc that I'm writing to the page using PHP. For some reason the output never includes the title node, and after researching I can't figure this out. If I change the title node to 'heading' or some other name it is included in the output, but when its named 'title', this node is skipped.
Here's the XML doc code...
<?xml version="1.0" encoding="UTF-8"?>
<items>
<product>
<id>cd1</id>
<title>CD One</title>
<description>This is my first CD</description>
<img>/images/sample.jpg</img>
<price>14.99</price>
</product>
</items>
The PHP code looks like this...
<?php
$filename = '../catalog.xml';
$contents = file_get_contents($filename);
echo $contents;
?>
Well, the XML you posted is not valid XML;
The encoding should be in lowercase. Try with this string:
<?xml version="1.0" encoding="utf-8"?>
<items>
<product>
<id>cd1</id>
<title>CD One</title>
<description>This is my first CD</description>
<img>/images/sample.jpg</img>
<price>14.99</price>
</product>
</items>
Validate here: http://validator.w3.org/check
I have some XML to which I need to add a child.
Using SimpleXML, I'm not having any issue adding a simple node.
The beginning XML looks a bit like this:
<root>
<item>
<title>This is the title</title>
<sort>2</sort>
</item>
<item>
<title>This is another title</title>
<sort>3</sort>
</item>
</root>
I need to add a node that looks like this:
<label id=1>
<title type=normal>This is a label</title>
<sort>1</sort>
</label>
The result would be:
<root>
<item>
<title>This is the title</title>
<sort>2</sort>
</item>
<item>
<title>This is another title</title>
<sort>3</sort>
</item>
<label id=1>
<title type=normal>This is a label</title>
<sort>1</sort>
</label>
</root>
I'm able to add a simple child using:
$xml->root->addChild('label', 'This is a label');
I am having trouble getting the attributes and children added to this newly added node though.
I am not worried about appending versus prepending as the sorting happens in XSLT.
addChild returns the added child, so you just have to do :
$label = $xml->root->addChild('label');
$label->addAttribute('id', 1);
$title = $label->addChild('title', 'This is a label');
$title->addAttribute('type', 'normal');
$label->addChild('sort', 1);
$xml->root->addChild('label', 'This is a label');
This opereration returns a reference to the child that was just added. So you could do this:
$child = $xml->root->addChild('label', 'This is a label');
From this, you can not add your additional children and attributes to that child.
$child->addAttributes('id', '1');
Since it returns a reference, that node and attributes that were just added are part of the $xml object as well.
I have two XML files (that have a number of common nodes) that look a bit like these:
DESTINATION FILE: ('destination.xml')
<items>
<item>
<title>Item A</title>
<description>This is the description for Item A</description>
<id>1001</id>
</item>
<item>
<title>Item B</title>
<description>This is the description for Item B</description>
<id>1002</id>
</item>
<item>
<title>Item D</title>
<description>This is the description for Item D</description>
<id>1004</id>
</item>
and
SOURCE FILE: ('source.xml')
<items>
<item>
<title>Item A</title>
<description>This is the description for Item A</description>
<id>1001</id>
</item>
<item>
<title>Item C</title>
<description>This is the description for Item C</description>
<id>1003</id>
</item>
<item>
<title>Item B</title>
<description>This is the description for Item B</description>
<id>1002</id>
</item>
I need to grab the node from SOURCE with the 'id' matching '1003' (in this example) and import it into the DESTINATION. I'm looking for insight in using importNode (or a simpleXML option) and also the xpath in only getting only the node I need.
Just do that and it should work :
<?php
header('Content-type: application/xml'); //Just to test in the browser directly and have a good format
$docSource = new DOMDocument();
$docSource->loadXML(file_get_contents('source.xml'));
$docDest = new DOMDocument();
$docDest->loadXML(file_get_contents('destination.xml'));
$xpath = new DOMXPath($docSource);
$result = $xpath->query('//item[id=1003]')->item(0); //Get directly the node you want
$result = $docDest->importNode($result, true); //Copy the node to the other document
$items = $docDest->getElementsByTagName('items')->item(0);
$items->appendChild($result); //Add the copied node to the destination document
echo $docDest->saveXML();
To get the correct node, I think your XPath should look like this:
$xpath->query('/items/item/id[.="1003"]/..')
To import it to the other document, you'll need to create the document and call importNode with the second parameter set to true:
$newDom = new DOMDocument;
$newDom->load('destination.xml');
$newNode = $newDom->importNode($el, true);
$newDom->firstChild->appendChild($newNode);
file_put_contents('destination.xml', $newDom->saveXML());
I am completely new to DOM Documents, basically what I am trying to do, is to load a RSS feed in and select only one node, and then save it to a XML file.
Here is the XML I am loading from a web feed:
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Markets</title>
<description/>
<link>http://www.website.com</link>
<language>en-us</language>
<copyright>XML Output Copyright</copyright>
<ttl>15</ttl>
<pubDate>Tue, 16 Nov 2010 09:38:00 +0000</pubDate>
<webMaster>admin#website.com</webMaster>
<image>
<title>title</title>
<url>http://www.website.com/images/xmllogo.gif</url>
<link>http://www.website.com</link>
<width>144</width>
<height>16</height>
</image>
<item>
<title>title</title>
<description>the description goes here
</description>
<enclosure url="http://www.website.com/images/image.png" type="image/png"/>
</item>
</channel>
</rss>
Here is my lame attempt at getting the <description> node and saving it to feed.xml:
<?php
$feed = new DOMDocument();
$feed->load('http://www.website.com/directory/directory/cz.c');
$nodeValue = $feed->getElementsByTagName('description')->item(0)->nodeValue;
$feed->save("feed.xml");
?>
So basically I need to get the description tag, and save it as a XML file.
Any help would be appreciated, thanx in advance!
Almost correct. To get the "outerXml" of a node, you can pass the node to saveXml()
$feed = new DOMDocument();
$feed->load('http://www.website.com/directory/directory/cz.c');
$xml = $feed->saveXml($feed->getElementsByTagName('description')->item(0));
file_put_contents("feed.xml", $xml);
Saving with file_put_contents will not include an XML prolog. Note that in your example, the first description element is empty, so the file will contain <description/>.
If you want to extract the node as standalone XML Document, you have to instantiate a new DOMDocument and import the DOMNode and then use save().
$dom = new DOMDocument($feed->xmlVersion, $feed->xmlEncoding);
$dom->appendChild(
$dom->importNode(
$feed->getElementsByTagName('description')->item(0),
TRUE
)
);
echo $dom->save('new.xml');
$feed = simplexml_load_file('feed.xml');
$descr=$feed->channel->description;
Try this