XPath - Get textcontent() and HTML - xpath

Lets say I have the following HTML:
<div class="some-class">
<p> some paragraph</p>
<h2>a heading</h2>
</div>
I want to grab everything in <div class='some-class'>, including the HTML. The following only grabs the text:
$descriptions = $xpath->query("//div[contains(#class, 'some-class')]");
foreach($descriptions as $description)
print $description->textContent;
Whats the best way of getting the contained HTML tags as well?

Use this function - I've never found any built in function but this works well:
function getInnerHTML($node)
{
$innerHTML = "";
$children = $node->childNodes;
foreach ($children as $child) {
$tmp_doc = new DOMDocument();
$tmp_doc->appendChild($tmp_doc->importNode($child,true));
$innerHTML .= $tmp_doc->saveHTML();
}
return $innerHTML;
}

I believe you are looking to retrieve the outerXml - have a look at DOMDocument::saveXML. Or have I misunderstood you - do you just need the xml serialization of the <div> element and its attribute axis?
Edit I mean do you want:
<div class="some-class">
<p> some paragraph</p>
<h2>a heading</h2>
</div>
or just
<div class="some-class" />
?

Related

I m trying to get the output of owl carousel dynamically using bootstrap but didnot get the desired output in codeigniter framework 3.0.1 version

This is what i want to display as slider when it slides both the rows move left or right correspondingly
a b c
a b c
<>
but what i have got is given below
a b c
<>
While getting images from database can't get the logic to display it by two rows.How is it possible??
<?php if($sliderimages):?>
<div class="owl-carousel client-slider owl-theme">
<?php foreach($sliderimages as $sliderimage):?>
<div class="item">
<div class="product-box">
<div class="product-img">
<img src="<?php echo base_url('assets/sliders/'.$sliderimage->file_name)?>" class="img-full" alt="" />
</div>
</div>
</div>
<?php else: ?>
<h5 class="text-alter"> sliders are not available</h5>
<?php endif;?>
</div>
In static condition the html code be like
<div class="owl-carousel client-slider owl-theme">
<div class="item">
<div class="product-box">
<div class="product-img"><img src="images/logos/Acer.jpg" class="img-full" alt=""/> </div>
<div class="product-img"><img src="images/logos/Alfa.jpg" class="img-full" alt=""/> </div>
</div>
</div>
I have to display images in carousel in two rows dynamically from database as static condition i have given above.The images fetch from db are to be placed in two rows. How can i get the result as static condition .Can anyone help me to solve this
I have updated my answer. With a simple CSS and HTML hack you don't need to alter the Javascript code, but you need to set some margins in your CSS and at initiation of your owl-carousel. Start by creating a flat array with file names in the sort order you want. This could be done in a Codeigniter Controller method or in the View:
// CREATE A FLAT ARRAY WITH JUST THE FILE NAMES FROM YOUR ORIGINAL ARRAY OF PHP OBJECTS
foreach($sliderimages as $sliderimage){
$result[] = $sliderimage->file_name;
}
// YOU NOW HAVE A FLAT ARRAY WITH FILE NAMES IN THE SORT ORDER YOU WANT TO DISPLAY THEM
// FOR EXAMPLE: array('1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg');
// NOW WE NEED TO ALTERNATE THE SORT ORDER IN THE ARRAY.
// 1: SPLIT THE ARRAY IN THE MIDDLE AND CREATE TWO NEW...
list($array1, $array2) = array_chunk($result, ceil(count($result) / 2));
// 2: EMPTY THE RESULT ARRAY TO MAKE ROOM FOR THE NEW RESULT
$result = array();
// COMBINE THE TWO NEW ARRAYS INTO ONE ARRAY WITH AN ALTERNATE SORT ORDER
array_map(function($item1, $item2) use (&$result)
{
$result[] = $item1;
$result[] = $item2;
}, $array1, $array2);
// WE USE FILTER TO REMOVE ARRAY ITEMS WITH EMPTY STRINGS
$result = array_filter($result);
Now we got an array with alternate sort order that is needed to be able to display the images in the sort order that you want with this suggested solution.
Loop through your result array and print the HTML. Here you need to control the odd and even rows to get it right:
// CREATE A COUNTER TO CHECK ODD/EVEN ROWS
$counter = 1;
// NUMBER OF IMAGES TOTAL
$number_of_images = count($result);
// IF WE HAVE IMAGES...
if($number_of_images > 0){
//START OWL CAROUSEL DIV
echo '<div class="owl-carousel owl-theme">';
foreach($result as $img) {
if ($counter % 2 == 0){ // EVEN ROW
echo ' <div class="product-box"><div class="product-img"><img src="'.base_url('assets/sliders/'.$img).'" class="img-full" alt=""/></div></div>';
// CLOSE ITEM DIV ON ODD ROWS
echo '</div>';
} else { // ODD
//OPEN A NEW DIV ITEM ON ODD ROWS
echo '<div class="item">';
// ECHO THE DIV WITH THE IMAGE
echo ' <div class="product-box"><div class="product-img"><img src="'.base_url('assets/sliders/'.$img).'" class="img-full" alt=""/></div></div>';
// CHECK TO SEE IF THIS IS THE LAST ROW
if($counter==$number_of_images){
// CLOSE ITEM DIV ON LAST ROW
echo '</div>';
}
} // END ODD/EVEN CHECK
$counter++;
} // END FOREACH
//END OWL CAROUSEL DIV
echo '</div>';
// NO SLIDER IMAGES AVAILABLE
} else {
echo '<h5 class="text-alter"> sliders are not available</h5>';
}
Now you should have printed HTML looking something like this:
<div class="owl-carousel owl-theme">
<div class="item">
<div class="product-box"><div class="product-img"><img src="images/logos/1.jpg" class="img-full" alt=""/></div></div>
<div class="product-box"><div class="product-img"><img src="images/logos/4.jpg" class="img-full" alt=""/></div></div>
</div>
<div class="item">
<div class="product-box"><div class="product-img"><img src="images/logos/2.jpg" class="img-full" alt=""/></div></div>
<div class="product-box"><div class="product-img"><img src="images/logos/5.jpg" class="img-full" alt=""/></div></div>
</div>
<div class="item">
<div class="product-box"><div class="product-img"><img src="images/logos/3.jpg" class="img-full" alt=""/></div></div>
<div class="product-box"><div class="product-img"><img src="images/logos/6.jpg" class="img-full" alt=""/></div></div>
</div>
</div>
The only thing you then have left to do is to set the margins for the images in CSS:
.product-box { margin-bottom: 10px; }
And set the margin and the number of images to show per row upon initiation of you owl-carousel (change the item property to items:4 if you want to show four images/row):
$('.owl-carousel').owlCarousel({
margin:10,
items:3
});
And the results should become:
Codepen example
https://codepen.io/MicKri/pen/vYpjqPy
More reading and examples
Owl carousel multiple rows
https://w3codemasters.in/multiple-rows-carousel-by-owl-carousel/

Simple dom document iteration

I have an HTML as so:
<html>
<body>
<div class="somethingunneccessary"></div>
<div class="container">
<div>
<p>text1</p>
<p>text2</p>
<p>text3</p>
</div>
<div>
<p>text4/p>
<p>text5</p>
<p>text6</p>
</div>
<div>
<p>text7</p>
<p>text8</p>
<p>text9</p>
</div>
<div>
<p>text10</p>
<p>text11</p>
<p>text12</p>
</div>
<div>
<p>text13</p>
<p>text14</p>
<p>text15</p>
</div>
</div>
</body>
</html>
What I'm trying to accomplish is the following:
1./ Loop over the div elements within the div having a class container.
2./ During the iteration I want to grab the text from the 3rd p tag.
The looping part is essential instead of just slicing out the p tags by themselves
I've got some code done but it doesn't do looping:
$doc=new DOMDocument();
$doc->loadHTML($htmlsource);
$xpath = new DOMXpath($doc);
$commentxpath = $xpath->query("/html/body/div[2]/div[5]/p[3]");
$commentdata = $commentxpath->item(0)->nodeValue;
How do I loop through each inner div element and extract the 3rd p tag.
Like I said, the looping is essential.
During the iteration I want to grab the text from the 3rd p tag
Try:
"//div[#class='container']/div/p[3]"
This should return all third p in all div inside of div with class container.
You may have to query over attributes: php xpath get attribute value
$xpath->query("/html/body/div[#class='container']");
Just try
/html/body/div/div//p
That should return only the p elements XD

How to make OR condition in Xpath query

I have two different type of html code:
my first code is:
<div class="course-general-info hide-for-medium-up">
<!-- TODO: check date format here -->
<div class="headline"><strong>2014-01-27</strong></div>
<div class="subline">Course start</div>
<div class="headline"><strong>2014-04-27</strong></div>
<div class="subline">Course end</div>
<div class="headline">Basis</div>
<div class="subline">Level</div>
</div>
my second code is:
<div class="course-general-info hide-for-medium-up">
<div class="headline">Available Soon</div>
<div class="subline">Course start</div>
<!-- TODO: check date format here -->
<div class="headline">Basis</div>
<div class="subline">Level</div>
</div>
i need to fetch the following value in single Xpath query
2014-01-27 or
Available Soon
my separate xpath queries are:
courseDurationDate = courseDetailData.xpath('//div[#class = "headline"]/strong/text()').extract()
CourseDutaionAvailableSoon = courseDetailData.xpath('//div[#class = "headline"]/text()').extract()
kindly help to write or condition in Xpath query. thanks in advance....
Assuming only one of the 2 divs will appear at the same time, this should do it:
(//div[#class = "headline"]/strong |
//div[#class = "headline" and not(strong)])[1]/text()
a one-liner
div[#class='course-general-info hide-for-medium-up']/div[#class='headline'][1]/descendant::text()
I tried following Xpath Query its worked for me:
courseDurationDate = courseDetailData.xpath('//div[#class = "course-general-info hide-for-medium-up"]/div[#class = "headline"]/strong/text() | \
//div[#class = "course-general-info hide-for-medium-up"]/div[#class = "headline" and not (strong)][1]/text()').extract()

getting all attribute values of spans inside a div

I have a div and inside of this, there are a lot of spans as follows:
<div id="mydiv">
<span id="first_id" itemindex="0">first span</span>
<span id="second_id" itemindex="1">second span</span>
<span id="third_id" itemindex="2">third span</span>
...
</div>
I want to define the function "getItemIndexValues()" in JQuery who get all values in "myDiv". It is possible?
You want to be using data- prefixed attributes.
HTML:
<div id="mydiv">
<span id="first_id" data-itemindex="0">first span</span>
<span id="second_id" data-itemindex="1">second span</span>
<span id="third_id" data-itemindex="2">third span</span>
</div>
JavaScript:
var arr = $( 'span', '#mydiv' ).map( function () {
return $( this ).data( 'itemindex' );
}).get();
Here, arr will be [ '0', '1', '2' ]
Live demo: http://jsfiddle.net/fQJAk/
Btw, if you prefer an array of numbers, do this:
return +$( this ).data( 'itemindex' );
-------^
I didn't verified it but I think this should work:
$("#mydiv>span").each(function(a,b){
alert($(b).attr('itemindex'));
});
By using the child selector here: http://api.jquery.com/child-selector/

Show only next and previous link in condeigniter pagination

I use codeigniter pagination class in my project it's works fine for me . But there is no option to tell class just show next and previous link ,
please see this image I want to show result paged plus I'd like to use to link for next and previous instead of numeric links and when the user click on the next button I'll use Ajax to retrieve request I don't have problem with Ajax calls in pagination in numeric links but I want to just show this to link :)
I don't think I can explain what I need very good so please see the image .
link text
Here is my view file :
<div style="height:200px; position:relative">
<div id="left_nav"></div>
<div id="right_nav"></div>
<div style="width:622px;margin:0 auto;">
<!-- Gallery Box1 -->
<?php foreach($last_profile as $l) : ?>
<div id="galleryBoxHolder">
<div id="galleryBoxContent">
<div id="ImageHolder">
<img src="dummy_data/1.gif" /> </div>
<br />
<p><?=$l->artname?> </p>
<br />
<p style="color:#1a4688">asdasd</p>
<p style="color:#1a4688 ; direction:ltr"><?=$l->length?> cm x <?=$l->width?> cm</p>
</div>
</div>
<?php endforeach ;?>
<div>
<?=$links?>
</div>
<!-- Gallery box1 :off -->
</div>
</div>
Please Check This url which is exactly what I need (#:title Customers Who Bought This Item Also Bought)
In version 2.0.3 Codeigniter - To show Next / Previous only you can add the following config settings:
$config['display_pages'] = FALSE;
$config['first_link'] = FALSE;
$config['last_link'] = FALSE;
You have a couple of options. The first is really simple, hide the thumbnails portion of the pagination module with CSS. The second options isn't too complex either: modify the pagination class to not include the thumbnails, and instead limit its output to the next/prev buttons. This should be somewhat trivial as well.
Line 199 of the System/Libraries/Pagination Library is where the "digits" are handled. This is where you will remove any appending to the $output variable:
if ($this->cur_page == $loop)
{
$output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page
}
else
{
$n = ($i == 0) ? '' : $i;
$output .= $this->num_tag_open.''.$loop.''.$this->num_tag_close;
}

Resources