I am looking for a way to find the value of a parameter 'duration' from an XML access
Source :
http://gdata.youtube.com/feeds/api/videos/bSCs7NzghSg
I tried something like :
preg_match('#<yt:duration seconds=\'(.*?)\'/>#is',$xml,$resultduration);
$duration = $resultTitre[count($resultduration)-1];
but value return 0
This can be done with SimpleXML. Use the children() method for finding the children and attributes() method for accessing the attributes.
Here's a function for that purpose:
function getDuration($url) {
$xml = simplexml_load_file($url);
$duration = $xml->children('media', true)
->group->children('yt', true)
->duration->attributes('', true)->seconds;
return $duration;
}
Usage:
$url = 'http://gdata.youtube.com/feeds/api/videos/bSCs7NzghSg';
echo getDuration($url); // => 2461
Demo!
$file = 'http://gdata.youtube.com/feeds/api/videos/bSCs7NzghSg';
$xml = simplexml_load_file($file);
$result = $xml->xpath('//yt:duration');
foreach ($result as $node) {
echo (double) $node['seconds'];
echo ' ';
}
Related
I have an XML product feed that I am parsing with PHP to load products into a database.
I need to get each element into an array of $products = array() such as:
$products[AttributeID] = value
This is what I have so far:
I am using simplexml and I have got most of it:
$xml = simplexml_load_file($CatalogFileName) or die("can't open file " . $CatalogFileName);
foreach($xml->children() as $products) {
foreach($products->children() as $product) {
$new_product = array();
$new_product[sku] = "AS-" . $product->Name;
foreach($product->Values->Value as $node) {
$node_name = preg_replace('/\s+/', '', $node[AttributeID]);
$new_product[$node_name] = $node[0]; **<--THIS IS NOT WORKING: $node[0] returns an array I only want the data in each attribute.**
}
foreach($product->AssetCrossReference as $node) {
$new_product[image] = "http://www.xxxxxxxx.com/images/items/fullsize/" . $node[AssetID] . ".jpg";
}
print_r($new_product);
}
}
Here is an image of one product node: XML
Can someone provide me with a little help here? I do a lot of PHP programming but this is the first time I am dealing with XML
A possbile solution is to use the xpath method to find the <Value> elements.
The xpath method will return an array of SimpleXMLElement objects.
These SimpleXMLElement objects have an attributes method which you can use to access the 'AttributeID' attribute.
I hope this example can help you:
$xml = simplexml_load_file($CatalogFileName) or die("can't open file " . $CatalogFileName);
$productsArray = array();
foreach($xml->children() as $products) {
foreach($products->children() as $product) {
$new_product = array();
$productId = (string)$product->attributes()->ID;
$new_product['NAME'] = "AS-" . (string)$product->Name;
// xpath will return an array of SimpleXMLElement objects
$values = $product->Values->xpath('//Value');
// use the attributes method to access the AttributeID
foreach ($values as $node) {
$attributeID = (string)$node->attributes()->AttributeID;
$new_product[$attributeID] = trim((string)$node);
}
$new_product['AssetID'] = sprintf(
"http://www.xxxxxxxx.com/images/items/fullsize/%s.jpg",
(string)$product->AssetCrossReference->attributes()->AssetID
);
// Add $new_product to $productsArray using the $productId as the array key
$productsArray[$productId] = $new_product;
}
}
See my PHP:
file = "routingConfig.xml";
global $doc;
$doc = new DOMDocument();
$doc->load( $file );
function traverseXML($ElTag, $attr = null, $arrayNum = 'all'){
$tag = $doc->getElementsByTagName($ElTag);
$arr = array();
foreach($tag as $el){
$arr[] = $el->getAttribute($attr);
}
if ($arrayNum == 'all'){
return $arr;
}else if(is_int($arrayNum)){
return $arr[$arrayNum];
}else{
return "Invalid $arrayNum value: ". $arrayNum;
};
}
echo traverseXML("Route", "type", 2);
XML is:
<Routes>
<Route type="source"></Route>
<Route></Route>
<Routes>
Error returned is:
Fatal error: Call to a member function getElementsByTagName() on a non-object
I'm not sure how to do this?
EDIT: Here is the actual code being used. I originally stripped it a little bit trying to make it easier to read, but I think my problem is related to using the function.
Your problem is that the global $doc; statement is outside the function, so the variable $doc is not defined inside the function.
This would fix it:
// ...
function traverseXML($ElTag, $attr = null, $arrayNum = 'all') {
global $doc;
// ...
...but
Global variables are bad news. They usually indicate poor design.
Really you should pass $doc in as an argument, like this:
function traverseXML($doc, $ElTag, $attr = null, $arrayNum = 'all'){
$tag = $doc->getElementsByTagName($ElTag);
$arr = array();
foreach($tag as $el){
$arr[] = $el->getAttribute($attr);
}
if ($arrayNum == 'all'){
return $arr;
}else if(is_int($arrayNum)){
return $arr[$arrayNum];
}else{
return "Invalid $arrayNum value: ". $arrayNum;
};
}
$file = "routingConfig.xml";
$doc = new DOMDocument();
$doc->load( $file );
echo traverseXML($doc, "Route", "type", 2);
Although you might consider whether you need the function at all - if you don't use it anywhere else in you application, you might as well just do this:
$file = "routingConfig.xml";
$ElTag = "Route";
$attr = "type";
$arrayNum = 2;
$doc = new DOMDocument();
$doc->load( $file );
$tag = $doc->getElementsByTagName($ElTag);
$arr = array();
foreach($tag as $el){
$arr[] = $el->getAttribute($attr);
}
if ($arrayNum == 'all'){
echo $arr;
}else if(is_int($arrayNum)){
echo $arr[$arrayNum];
}else{
echo "Invalid $arrayNum value: ". $arrayNum;
};
The $doc variable is not defined inside your function. You have two options:
Pass $doc as one of the function arguments, which is preferred.
Write global $doc; at the top of your function ... devs usually try to avoid globals.
My file xml:
<pasaz:Envelope>
<pasaz:Body>
<loadOffe>
<offe>
<off>
<id>120023</id>
<name>my name John</name>
<name>Test</name>
</off>
</offe>
</loadOffe>
</pasaz:Body>
</pasaz:Envelope>
How to view a php (id and name).
If you're just looking for a simple way to extract the contents of a tag, but don't want to go to all the trouble of parsing the XML properly, you could do something like this:
$xml = ""; // your xml data as a string
function get_tag_contents($xml, $tagName) {
$startPosition = strpos($xml, "<" . $tagName . ">");
$endPosition = strpos($xml, "</" . $tagName . ">");
$length = $endPosition - ($startPosition + 1);
return substr($xml, $startPosition, $length);
}
$id = get_tag_contents($xml, "id");
$name = get_tag_contents($xml, "name");
This assumes you haven't assigned any attributes to your tags, and that each tag is unique (in the example you gave us I noted two "name" tags, and if you want both you'll need to make this solution a bit more robust or do proper XML parsing).
How to get all items?
Example (does not work ..)
$pliks = simplexml_load_file("file.xml");
foreach ($pliks->children('pasaz', true) as $body)
{
foreach ($body->children() as $loadOffe)
{
if ($loadOffe->offe->off) {
echo "<p>id: $loadOffe->id</p>";
echo "$id->id";
echo "<p>name: <b>$name->name</b></p>";
}
}
// echo $loadOffe->offe->off->id;
}
As Marc B suggested in his comment you should use DOM, either use getElementsByTagName() or DOMXPath, example for getElementaByTagName():
$dom = new DOMDocument;
$dom->loadXML($xml);
$ids = $dom->getElementsByTagName('id');
if( $ids || !$ids->length){
throw new Exception( 'Id not found');
}
return $ids->item(0);
I have following code.
<entry>
<job:location>
<job:id>24</job:id>
<job:region>6</job:region>
</job:location>
</entry>
I've problem with namespaces. How I can read content of job:region tag in SimpleXML.
Try this:
<?php
$entry = simplexml_load_file('entry.xml');
printf("%s\n", $entry->children('job', true)->location->region);
?>
To check the above code in action, click here
For more information about SimpleXml refer to this article
You should register the job namespace, then you can use the registered namespace-prefix in an XPath to select what you want:
$sxe = new SimpleXMLElement($xml);
$sxe->registerXPathNamespace('job', 'http://example.org/you-did-not-provide-the-job-namespaceURI-in-your-example');
$result = $sxe->xpath('//entry/job:location/job:region');
foreach ($result as $location) {
echo $location . "\n";
}
I would do it dynamically.
$xml = #simplexml_load_string($path) // loads your valid xml data
foreach($xml->channel->item as $entry) {
$namespaces = $entry->getNameSpaces(true);
foreach($namespaces as $ns=>$value)
{
$job = $entry->children($namespaces[$ns]);
$author = (string)$job->creator;
if ($author != "")
{
$someVariable = (string) $dc->creator;
}
}
I have the following code at the moment:
$ip = '195.72.186.157';
$xmlDoc = new DOMDocument();
$xmlDoc->loadXML(file_get_contents('http://www.geoffmeierhans.com/services/geo-locator/locate/?ip='.$ip.'&output=xml'));
foreach($xmlDoc->getElementsByTagName('city') as $link) {
$links = array('text' => $link->nodeValue);
}
$city = $links['text'];
echo $city;
Is there a better way to get the city variable? Since there is only one tag called city a loop isn't really needed but I can't get it to work any other way
Well, you can use the length parameter to DomNodeList (what's returned by the getElementsByTagName call.
If you want only the first result:
$nodes = $xmlDoc->getElementsByTagName('city');
if ($nodes->length > 0) {
$city = $nodes->item(0)->nodeValue;
} else {
$city = ''; // There is no city element
}