I have a PHP function creating a DOMDocument XML file, i need to get the DOMDocument into Javascript, i have thought about using
The function in PHP returns the DOMDocument, this is the PHP function
function coursexml($cc, $type){
$xmlfile = new DOMDocument();
if (#$xmlfile->load("books.xml") === false || $cc == "" || $type == "") {
header('location:/assignment/errors/500');
exit;
}
$string = "";
$xpath = new DOMXPath($xmlfile);
$nodes = $xpath->query("/bookcollection/items/item[courses/course='$cc']");
$x = 0;
foreach( $nodes as $n ) {
$id[$x] = $n->getAttribute("id");
$titles = $n->getElementsByTagName( "title" );
$title[$x] = $titles->item(0)->nodeValue;
$title[$x] = str_replace(" /", "", $title[$x]);
$title[$x] = str_replace(".", "", $title[$x]);
$isbns = $n->getElementsByTagName( "isbn" );
$isbn[$x] = $isbns->item(0)->nodeValue;
$bcs = $n->getElementsByTagName( "borrowedcount" );
$borrowedcount[$x] = $bcs->item(0)->nodeValue;
if ($string != "") $string = $string . ", ";
$string = $string . $x . "=>" . $borrowedcount[$x];
$x++;
}
if ($x == 0) header('location:/assignment/errors/501');
$my_array = eval("return array({$string});");
asort($my_array);
$coursexml = new DOMDocument('1.0', 'utf-8');
$coursexml->formatOutput = true;
$node = $coursexml->createElement('result');
$coursexml->appendChild($node);
$root = $coursexml->getElementsByTagName("result");
foreach ($root as $r) {
$node = $coursexml->createElement('course', "$cc");
$r->appendChild($node);
$node = $coursexml->createElement('books');
$r->appendChild($node);
$books = $coursexml->getElementsByTagName("books");
foreach ($books as $b) {
foreach ($my_array as $counter => $bc) {
$bnode = $coursexml->createElement('book');
$bnode = $b->appendChild($bnode);
$bnode->setAttribute('id', "$id[$counter]");
$bnode->setAttribute('title', "$title[$counter]");
$bnode->setAttribute('isbn', "$isbn[$counter]");
$bnode->setAttribute('borrowedcount', "$borrowedcount[$counter]");
}
}
}
return $coursexml;
}
So what i want to do is call the function in Javascript, and returns the DOMDocument.
Try the following
<?php include('coursexml.php'); ?>
<script>
var xml = <?php $xml = coursexml("CC140", "xmlfile");
echo json_encode($xml->saveXML()); ?>;
document.write("output" + xml);
var xmlDoc = (new DOMParser()).parseFromString(xml, 'text/xml');
</script>
you can simply put this function to a URL ( eg have it in a standalone file? that's up to you ), and call it from the client side via AJAX. For details on doing such a call, please reference How to make an AJAX call without jQuery? .
Edit:
try to create a simple PHP file that includes and calls the function you have. From what you've described so far, it will probably look like
<?php
include("functions.php");
print coursexml($cc, $type);
assuming this file is called xml.php , when you access it via your browser in http://mydomain.com/xml.php you should see the XML document (nothing related to Javascript so far).
Now, in your main document, you include a piece of Javascript that will call upon this URL to load the XML. An example would be (assuming you are using jQuery, for a simple Javascript function reference the above link) :
$.ajax({
url: "xml.php",
success: function(data){
// Data will contain you XML and can be used in Javascript here
}
});
Related
So i like to take vine image url and video url using PHP Simple HTML DOM Parser.
http://simplehtmldom.sourceforge.net/
here is a example vine url
https://vine.co/v/bjHh0zHdgZT
So i need to take this info from the URL. Form image URL:
<meta property="twitter:image" content="https://v.cdn.vine.co/v/thumbs/8B474922-0D0E-49AD-B237-6ED46CE85E8A-118-000000FFCD48A9C5_1.0.6.mp4.jpg?versionId=mpa1lJy2aylTIEljLGX63RFgpSR5KYNg">
and For the video URL
<meta property="twitter:player:stream" content="https://v.cdn.vine.co/v/videos/8B474922-0D0E-49AD-B237-6ED46CE85E8A-118-000000FFCD48A9C5_1.0.6.mp4?versionId=ul2ljhBV28TB1dUvAWKgc6VH0fmv8QCP">
I want to take only the content of the these meta tags. if anyone can help really appreciate it. Thanks
Instead of using the lib you pointed out, I'm using native PHP DOM in this example, and it should work.
Here's a small class I created for something like that:
<?php
class DomFinder {
function __construct($page) {
$html = #file_get_contents($page);
$doc = new DOMDocument();
$this->xpath = null;
if ($html) {
$doc->preserveWhiteSpace = true;
$doc->resolveExternals = true;
#$doc->loadHTML($html);
$this->xpath = new DOMXPath($doc);
$this->xpath->registerNamespace("html", "http://www.w3.org/1999/xhtml");
}
}
function find($criteria = NULL, $getAttr = FALSE) {
if ($criteria && $this->xpath) {
$entries = $this->xpath->query($criteria);
$results = array();
foreach ($entries as $entry) {
if (!$getAttr) {
$results[] = $entry->nodeValue;
} else {
$results[] = $entry->getAttribute($getAttr);
}
}
return $results;
}
return NULL;
}
function count($criteria = NULL) {
$items = 0;
if ($criteria && $this->xpath) {
$entries = $this->xpath->query($criteria);
foreach ($entries as $entry) {
$items++;
}
}
return $items;
}
}
To use it you can try:
$url = "https://vine.co/v/bjHh0zHdgZT";
$dom = new DomFinder($url);
$content_cell = $dom->find("//meta[#property='twitter:player:stream']", 'content');
print $content_cell[0];
I need to get all of the text contained between a specific div. In the following example I want to get everything between the div with class name "st" :
<div class="title">This is a title</div>
<div class="st">Some example <em>text</em> here.</div>
<div class="footer">Footer text</div>
So the result would be
Some example <em>text</em> here.
or even just
Some example text here.
Does anyone know how to accomplish this?
Server-side in PHP
A very basic way would be something like this:
$data = ''; // your HTML data from the question
preg_match( '/<div class="\st\">(.*?)<\/div>/', $data, $match );
Then iterate the $match object. However, this could return bad data if your .st DIV has another DIV inside it.
A more proper way would be:
function getData()
{
$dom = new DOMDocument;
$dom -> loadHTML( $data );
$divs = $dom -> getElementsByTagName('div');
foreach ( $divs as $div )
{
if ( $div -> hasAttribute('class') && strpos( $div -> getAttribute('class'), 'st' ) !== false )
{
return $div -> nodeValue;
}
}
}
Client-side
If you're using jQuery, it would be easy like this:
$('.st').text();
or
$('.st').html();
If you're using plain JavaScript, it would be a little complicated cause you'll have to check all DIV elements until you find the one with your desired CSS class:
function foo()
{
var divs = document.getElementsByTagName('div'), i;
for (i in divs)
{
if (divs[i].className.indexOf('st') > -1)
{
return divs[i].innerHTML;
}
}
}
Use DOM. Example:
$html_str = "<html><body><div class='st'>Some example <em>text</em> here.</div></body></html>";
$dom = new DOMDocument('1.0', 'iso-8859-1');
$dom->loadHTML($html_str); // just one method of loading html.
$dom->loadHTMLFile("some_url_to_html_file");
$divs = getElementsByClassName($dom,"st");
$div = $divs[0];
$str = '';
foreach ($div->childNodes as $node) {
$str .= $dom->saveHTML($node);
}
print_r($str);
The below function is not mine, but this user's. If you find this function useful, go to the previously linked answer and vote it up.
function getElementsByClassName(DOMDocument $domNode, $className) {
$elements = $domNode->getElementsByTagName('*');
$matches = array();
foreach($elements as $element) {
if (!$element->hasAttribute('class')) {
continue;
}
$classes = preg_split('/\s+/', $element->getAttribute('class'));
if (!in_array($className, $classes)) {
continue;
}
$matches[] = $element;
}
return $matches;
}
PHP is a server side language, to do this you should use a client side language like javascript (and possibly a library like jQuery for easy ad fast cross-browser coding). And then use javascript to send the data you need to the backend for processing (Ajax).
jQuery example:
var myText = jQuery(".st").text();
jQuery.ajax({
type: 'POST',
url: 'myBackendUrl',
myTextParam: myText,
success: function(){
alert('done!');
},
});
Then, in php:
<?php
$text = $_POST['myTextParam'];
// do something with text
Using a XML parser:
$htmlDom = simple_load_string($htmlSource);
$results = $htmlDom->xpath("//div[#class='st']/text()");
while(list( , $node) = each($result)) {
echo $node, "\n";
}
use jquery/ajax
then do something like:
<script>
$(document).ready(function() {
$.ajax({
type: "POST",
url: "urltothepageyouneed the info",
data: { ajax: "ajax", divcontent:$(".st").html()}
})
});
</script>
Basically
$(".st").html()
will return the HTML
and
$(".st").text()
Will return the text
Hope that helps
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.
I am editing a xml file a particular node file after tha I am saving tha but it contains some special character because of line number 7 of my code
$xml = simplexml_load_file('demo.xml');
$i=2;
foreach($xml->Page as $myPage){
if($myPage['id']==$i) {
$da = "data";
$text = "helloworld";
$myPage->$da ="<![CDATA[{$text}]]>"; //line number
$xml->asXML('demo.xml');
}
how can I put the string as it is in xml file?
SimpleXML does not handle CDATA very well. If you want to write CDATA you need to use the DOM objects. For example:
$xml = new DOMDocument();
$xml->load('demo.xml');
$i = 2;
foreach ($xml->getElementsByTagName('Page') as $page) {
if ($page->attributes->getNamedItem('id')->value == $i) {
$da = 'data';
$text = 'helloworld';
$data = $xml->createElement($da);
$data->appendChild($xml->createCDATASection($text));
$page->appendChild($data);
}
}
If you want to continue to use SimpleXML, you can load just the element you want to write the CDATA into as a DOM object.
$xml = simplexml_load_file('demo.xml');
$i = 2;
foreach ($xml->Page as $page) {
if ($page['id'] == $i) {
$da = 'data';
$text = 'helloworld';
$page->$da = '';
$node = dom_import_simplexml($page->$da);
$dom = $node->ownerDocument;
$node->appendChild($dom->createCDATASection($text));
}
}
$xml->asXML('demo.xml');
Ok, so I'm writing an application in PHP to check my sites if all the links are valid, so I can update them if I have to.
And I ran into a problem. I've tried to use SimpleXml and DOMDocument objects to extract the tags but when I run the app with a sample site I usually get a ton of errors if I use the SimpleXml object type.
So is there a way to scan the html document for href attributes that's pretty much as simple as using SimpleXml?
<?php
// what I want to do is get a similar effect to the code described below:
foreach($html->html->body->a as $link)
{
// store the $link into a file
foreach($link->attributes() as $attribute=>$value);
{
//procedure to place the href value into a file
}
}
?>
so basically i'm looking for a way to preform the above operation. The thing is I'm currently getting confused as to how should I treat the string that i'm getting with the html code in it...
just to be clear, I'm using the following primitive way of getting the html file:
<?php
$target = "http://www.targeturl.com";
$file_handle = fopen($target, "r");
$a = "";
while (!feof($file_handle)) $a .= fgets($file_handle, 4096);
fclose($file_handle);
?>
Any info would be useful as well as any other language alternatives where the above problem is more elegantly fixed (python, c or c++)
You can use DOMDocument::loadHTML
Here's a bunch of code we use for a HTML parsing tool we wrote.
$target = "http://www.targeturl.com";
$result = file_get_contents($target);
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
#$dom->loadHTML($result);
$links = extractLink(getTags( $dom, 'a', ));
function extractLink( $html, $argument = 1 ) {
$href_regex_pattern = '/<a[^>]*?href=[\'"](.*?)[\'"][^>]*?>(.*?)<\/a>/si';
preg_match_all($href_regex_pattern,$html,$matches);
if (count($matches)) {
if (is_array($matches[$argument]) && count($matches[$argument])) {
return $matches[$argument][0];
}
return $matches[1];
} else
function getTags( $dom, $tagName, $element = false, $children = false ) {
$html = '';
$domxpath = new DOMXPath($dom);
$children = ($children) ? "/".$children : '';
$filtered = $domxpath->query("//$tagName" . $children);
$i = 0;
while( $myItem = $filtered->item($i++) ){
$newDom = new DOMDocument;
$newDom->formatOutput = true;
$node = $newDom->importNode( $myItem, true );
$newDom->appendChild($node);
$html[] = $newDom->saveHTML();
}
if ($element !== false && isset($html[$element])) {
return $html[$element];
} else
return $html;
}
You could just use strpos($html, 'href=') and then parse the URL. You could also search for <a or .php