I am trying to insert nodes in my html string.
My goal is to insert an element before each h2 tag.
For that, I am using:
$htmlString = "<h2>some html</h2>";
$DOM = new DOMDocument();
$DOM->loadHTML($htmlString);
$itemTitles = $DOM->getElementsByTagName('h2');
for($i = 0; $i < $itemTitles->length; $i ++)
{
$helpNavigatorContents[] = $itemTitles->item($i)->nodeValue;
$textBefore = new DOMNode(
'<a name="'.$itemTitles->item($i)->nodeValue.'"></a>'
);
$itemTitles->item($i)->parentNode->insertBefore(
$textBefore,
$itemTitles->item($i)
);
}
$htmlString = $DOM->saveHTML($DOM);
And here I have a problem with the $textBefore. When I declare the $textBefore as a DOMText, I can insert the text before the node but when I try this with DOMNode, then I am getting the following error (Demo):
Warning: DOMNode::insertBefore(): Couldn't fetch DOMNode
The code doesn't make any sense. DOMNode does not have a constructor. It is not supposed to be created at all. You are supposed to create specific node types through DOMDocument to have them associated with the Document.
Assuming you want to prepend all the H2 element with an anchor, this is how to do it:
libxml_use_internal_errors(true);
$DOM = new DOMDocument();
$DOM->loadHTML($htmlString);
$DOM->preserveWhiteSpace = false;
foreach ($DOM->getElementsByTagName('h2') as $h2) {
$a = $DOM->createElement('a');
$a->setAttribute('name', $h2->nodeValue);
$h2->parentNode->insertBefore($a, $h2);
}
$DOM->formatOutput = true;
echo $DOM->saveHTML();
Demo http://codepad.org/N0dPcLwT
To wrap the H2 elements into the A element, simply do the same and add
$a->appendChild($h2);
Demo http://codepad.org/w7Hi0Bmz
Related
Laravel Package:
"setasign/fpdi": "^2.3",
"setasign/fpdf": "^1.8"
$pdf = new \setasign\Fpdi\Fpdi('L','mm','A4');
$pageCount = $pdf->setSourceFile(public_path().'/'.$url);
$pdf->setFont('Arial', 'B', 10);
for($i = 1; $i <= $pageCount; $i++){
$tplIdx = $pdf->importPage($i);
$pageDimensions = $pdf->getImportedPageSize($tplIdx);
$pdf->addPage($pageDimensions['orientation'], $pageDimensions);
$pdf->useTemplate($tplIdx);
}
If It Possible read the content of the last page and get after page content ordinate of the current position. then Write new content without add new page or whitespaces
If Pdf Generate using DomPdf so you can generate HTML file using
$pdf->getDomPDF()->outputHtml()
Generated html file using DomPDF add some element like this:
<div id="divId"></div>
Then whenever you need to edit this document, you need to read the HTML file line by line and
Edit document:
$url=public_path() .'/test.html';
$htmlFile='';
foreach(file($url) as $key => $line){
if(strpos($line, 'id="divId"') !== false){
$line='<div>Hello world</div>';
}
$htmlFile.=$line;
}
$pdf = PDF::loadHTML($htmlFile)->setPaper('a4', 'landscape');
$pdf->output();
Not sure I am doing this correctly as it doesn't appear to be working.
Is this the correct way to declare my users, and is the If statement correctly formated?
At the top I have declared:
my $las = 'jpietrza hpietrza oszones';
These are employees we are checking against current users.
Further down in the code, I want to change the text color that is printed if the user is in the list vs. someone else.
while ( $sth->fetch() ) {
next unless defined $currentuser;
$lastlogin =~ s/ .*$//;
$host_name =~ s/1408//;
foreach ( #las ) {
if ( $currentuser eq "$_" ) {
$lacolor = "black";
last;
}
else {
$lacolor = "red";
}
}
print "<tr>";
print "<td>$host_name</td>";
print "<td><font color=\"$lacolor\">System In-Use (User Undisclosed)</font></td><td> </td>";
}
maybe there was nothing wrong with the if statement, but the whole 9 lines of code can be condensed to 1 very readable line:
$lacolor = any { /^$currentuser$/ } #las ? "black" : "red";
please
use List::Util qw/any/;
while($sth->fetch()) {
# $currentuser is assigned between the 'while' and this 'next' statement ?
# if not, then outside the loop and do not loop at all unless defined
next unless defined $currentuser;
$lastlogin=~s/ .*$//;
$host_name=~s/1408//;
$lacolor = any { /^$currentuser$/ } #las ? "black" : "red";
print "<tr>";
print "<td>$host_name</td>";
print "<td><font color=\"$lacolor\">System In-Use (User Undisclosed)</font></td><td> </td>";
}
please, also use strict; and use warnings;
I figured out how to put the array together correctly:
my #las = qw(
jpietrza
hpietrza
oszones
);
instead of:
my $las='
jpietrza
hpietrza
oszones
';
Firstly, as I think you have worked out now, the scalar variable $las and the array #las are completely different. As you've seen, you should declare and initialise your array like this:
my #las = qw(
jpietrza
hpietrza
oszones
);
Actually, I suspect this all gets easier if you store this in a hash, not an array;
my %las = map { $_ => 1 } qw(jpietrza hpietrza oszones);
Then your check just becomes:
my $lacolour = $las{$currentuser} ? 'black' : 'red';
A few more points:
Please add use strict and use warnings. And understand and fix the problems they reveal.
The quotes are unnecessary in if ($currentuser eq "$_").
Using a templating system to create the output will make your life a lot easier.
Update: Oh, and one I forgot earlier. It's 2017. No-one has used the font element in HTML for fifteen years. Take a look at CSS.
The code below works for a string value but not when I try to access the variable directly.
The data being accessed is a table at http://webrates.truefx.com/rates/connect.html?f=html
My code strips it of tags and put it in an array $row0
And puts it in a function. But I can't get it out. The function is simplified for this question. I intend to concatenate some of the variables inside the function once I find out what I'm doing wrong.
$row0 = array();
include "scrape/simple_html_dom.php";
$url = "http://webrates.truefx.com/rates/connect.html?f=html";
$html = new simple_html_dom();
$html->load_file($url);
foreach ($html->find('tr') as $i => $row) {
foreach ($row->find('td') as $j => $col) {
$row0[$i][$j]= strip_tags($col);
}
}
myArray($row0); //table stripped of tags
function myArray($arr) {
$a = 'hello'; //$arr[0][0]; HELLO will come out but not the variable
$b = $arr[1][0];
$r[0] = $a;
$r[1] = $b;
//echo $r[1]; If the //'s are removed one can see the proper value here but not outside the function.
return $r;
}
$arrayToEcho = myArray($arr);
echo $arrayToEcho[0]; // will echo "first"
I have tried all the suggestions from here:
http://stackoverflow.com/questions/3451906/multiple-returns-from-function
http://stackoverflow.com/questions/5692568/php-function-return-array
Suggestion appreciated please and more info available if required. Thank you very much for viewing.
You need to get the innertext of $col in your loop. Like this:
$row0[$i][$j]= $col->innertext;
The next thing is:
myArray($row0);
This call will correctly return the parsed array; try echoing it and you'll see. But when you do this:
$arrayToEcho = myArray($arr);
...you're referencing to $arr which is a local variable (a parameter, actually) inside your function myArr. So what you probably meant was this:
$arrayToEcho = myArray($row0);
Hope this helps!
UPDATE
Look, I show you what happens when you call a function:
I'm trying to extract the HTML content present in < td > tags corresponding to the class "tablehead1".
< td class="tablehead1"> Market < /td >
While parsing, i'm getting all the text contents of < td > tags present in the whole html file.
But I need only the content in < td > tags with the particular class "tablehead1" .
Where am i going wrong in the below code ?
use HTML::TokeParser;
open(DATA,"<KeyStats.html") or die "Can't open data";
my $p = HTML::TokeParser->new(*DATA);
while (my $token = $p->get_tag('td')) {
my $url = $token->[1]{class} || "tablehead1";
my $text = $p->get_trimmed_text("/td");
if (length($text)<30&&length($text)>0) { print "$text\n"; }
}
You don't really perform the check whether the class is really tablehead1.
Replace
my $url = $token->[1]{class} || "tablehead1";
by
next unless $token->[1]{class} eq "tablehead1";
should give you the expected results. Also, you should add a check whether the actual <td> really has a key class, e.g. by
next unless grep( /^class$/, #{$token->[2]} ) && $token->[1]{class} eq "tablehead1";
I have to extract data from this link: http://bit.ly/l1rF5x
What I want to do is that I want to extract all p tags which comes under the <a> tag having attribute rel="bookmark". My only requirement is that only <p> tags which comes under this heading should be parsed, and remaining should be left as it is. Like for example in this page which I have given you, all <p> tags which comes under heading "IIFT question paper 2006", should be parsed.
help please.
You can try using the following :
$(function(){
var results= '';
$('a[rel="bookmark"] p').each(function(i,e){
results += $(e).html() + "\n";
});
alert(results);
});
Variable results will be alerted with the required content.
Example : http://jsfiddle.net/eGmWw/1/
Since you haven't provided any information about the language / environment you want to use to extract this information, I've gone ahead and hacked something together with jQuery.
(Updated) You can see it in action here: JS Fiddle.
If you wanted to use PHP, I recommend simplehtmldom
Here is an example using simplehtmldom:
$url = 'http://school-listing.mba4india.com/page/7/';
$html = file_get_html($url);
$data = array();
// Find all anchors with the desired rel attribute
foreach ($html->find('a[rel="bookmark"]') as $a) {
$h4 = $a->parent(); // Get the anchors parent (in this case an h4)
// We're assuming the next sibling is a p tag here - should test for this here
$p = $h4->next_sibling();
$content = '';
// Iterate over all following p tags, until we run out of siblings or find one
// that isn't a p tag
while ($p) {
$content .= (string) $p;
if ($p->next_sibling() && $p->next_sibling()->tag == 'p') {
$p = $p->next_sibling();
} else {
break;
}
}
$data[] = array('h4' => $h4, 'content' => $content);
}
$br = '<br/>';
foreach ($data as $datum) {
echo $datum['h4'] . $br . $datum['content'];
echo $br.$br;
}
Refer to Simplehtmldom Documentation for more!