my smarty code is like this i want to add new tr after adding two td $k is counter variable with this code i can not add new tr after every two td
{section name="sec" loop=$dataArray}
<tr>
{if ($k%2) == 0}
<td>{$dataArray[sec].itemNm}</td>
<td>{$dataArray[sec].rate}</td>
<td>{$dataArray[sec].unitId}</td>
<td>{$dataArray[sec].packing}</td>
</tr>
{/if}
{/section}
My Php Select Query is like
$selectdata = "SELECT *,itemNm FROM price
JOIN item ON item.itemId = price.itemId
WHERE price.companyId = ".$companyId;
$selectdataRes = mysql_query($selectdata);
while($dataRow = mysql_fetch_array($selectdataRes))
{
$dataArray[$k]['priceId'] = $dataRow['priceId'];
$dataArray[$k]['itemNm'] = $dataRow['itemNm'];
$dataArray[$k]['rate'] = $dataRow['rate'];
$dataArray[$k]['unitId'] = $dataRow['unitId'];
$dataArray[$k]['packing'] = $dataRow['packing'];
$k++;
}
You increment $k every loop of mysql_fetch_array, which means $k is the number of the row (aka TR in your HTML). If your SQL query returns 4 lines, each containing a priceId, itemNm, rate, unitId and packing.
Normally in your HTML, to represent it in a common table, you would have 4 lines TR (one TR for each row) with a column TD for each data you want to display (one TD for each data).
{section name="sec" loop=$dataArray}
<tr>
<td>{$dataArray[sec].itemNm}</td>
<td>{$dataArray[sec].rate}</td>
<td>{$dataArray[sec].unitId}</td>
<td>{$dataArray[sec].packing}</td>
</tr>
{/section}
If you perform a $k%2 == 0, you reach it every two rows (every two TR), not every two TD. If you want to close TR and open new TR every two TD and not every two TR, you have to handle your TDs in a loop and start another incrementing variable like this (example neither with smarty nor in any language in particular, just an idea of algorithm) :
for($k=0;$k<$numLines;$k++)
{
<tr>
for($l=0;$l<$numColumns;$l++)
{
if($l > 0 && $l%2 == 0)
{
</tr><tr>
}
<td>$myData[$l]</td>
}
</tr>
}
Hoping it helps :)
Your question is very hard to understand...
Do you want to split every data row in two table rows?
Since you have a static template, you can add table rows inside your loop, whereever you want. I see no need to use multiple loops.
{section name="sec" loop=$dataArray}
<tr>
<td>{$dataArray[sec].itemNm}</td>
<td>{$dataArray[sec].rate}</td>
</tr>
<tr>
<td>{$dataArray[sec].unitId}</td>
<td>{$dataArray[sec].packing}</td>
</tr>
{/section}
if this does not fit your needs, maybe could you provide an example output as you need it?
Related
Using XPath to webscrape.
The structure is:
<table>
<tbody>
<tr>
<th>
<td>
but one of those tr has contains just one th or one td.
<table>
<tbody>
<tr>
<th>
So I just want to scrape if TR contains two tags inside it. I am giving the path
$route = $path->query("//table[count(tr) > 1]//tr/th");
or
$route = $path->query("//table[count(tr) > 1]//tr/td");
But it's not working.
I am giving the orjinal table's links here. First table's last two TR is has just one TD. That is causing the problem. And 2nd or 3rd table has same issue as well.
https://www.daiwahouse.co.jp/mansion/kanto/tokyo/y35/gaiyo.html
$route = $path->query("//tr[count(*) >= 2]/th");
foreach ($route as $th){
$property[] = trim($th->nodeValue);
}
$route = $path->query("//tr[count(*) >= 2]/td");
foreach ($route as $td){
$value[] = trim($td->nodeValue);
}
I am trying to select TH and TD at the same time. BUT if TR has contains one TD then it caunsing the problem. Because in the and TD count and TH count not same I am scraping more TD then the TH
This XPath,
//table[count(.//tr) > 1]/th
will select all th elements within all table elements that have more than one tr descendent (regardless of whether tbody is present).
This XPath,
//tr[count(*) > 1]/*
will select all children of tr elements with more than one child.
This XPath,
//tr[count(th) = count(td)]/*
will select all children of tr elements where the number of th children equals the number of td children.
OP posted a link to the site. The root element is in the xmlns="http://www.w3.org/1999/xhtml" namespace.
See How does XPath deal with XML namespaces?
If I understand correctly, you want th elements in trs that contain two elements? I think that this is what you need:
//th[count(../*) = 2]
I've included a more explicit path in my answer with a or statement to count TH and TD elements
$html = '
<html>
<body>
<table>
<tbody>
<tr>
<th>I am Included</th>
<td>I am a column</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<th>I am ignored</th>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<th>I am also Included</th>
<td>I am a column</td>
</tr>
</tbody>
</table>
</body>
</html>
';
$doc = new DOMDocument();
$doc->loadHTML( $html );
$xpath = new DOMXPath( $doc );
$result = $xpath->query("//table[ count( tbody/tr/td | tbody/tr/th ) > 1 ]/tbody/tr");
foreach( $result as $node )
{
var_dump( $doc->saveHTML( $node ) );
}
// string(88) "<tr><th>I am Included</th><td>I am a column</td></tr>"
// string(93) "<tr><th>I am also Included</th><td>I am a column</td></tr>"
You can also use this for any depth descendants
//table[ count( descendant::td | descendant::th ) > 1]//tr
Change the xpath after the condition (square bracketed part) to change what you return.
This question already has answers here:
How do you parse and process HTML/XML in PHP?
(31 answers)
Closed 6 years ago.
I am fetching html from a website with file_get_contents. I have a table (with a class name) inside html, and I want to get the data inside html tags.
This is how I fetch the html data from url:
$url = 'http://example.com';
$content = file_get_contents($url);
The html looks like:
<table class="space">
<thead></thead>
<tbody>
<tr>
<td class="marsia">1</td>
<td class="mars">
<div>Mars</div>
</td>
</tr>
<tr>
<td class="earthia">2</td>
<td class="earth">
<div>Earth</div>
</td>
</tr>
</body>
</table>
Is there a way to searh DOM elements in php like we do in jQuery? So that I can access the values 1, 2 (first td) and div's value inside second td.
Something like
a) search the html for table with class name space
b) inside that table, inside tbody, return each tr's 'first td's value' and 'div's value inside second td'
So I get; 1 and Mars, 2 and Earth.
Use the DOM extension, for example. Its DOMXPath class is particularly useful for such kind of tasks.
You can easily set the listed conditions with an XPath expression like this:
//table[#class="space"]//tr[count(td) = 2]/td
where
- //table[#class="space"] selects all table elements from the document having class attribute value equal to "space" string;
- //tr[count(td) = 2] selects all tr elements having exactly two td child elements;
- /td represents the td elements.
Sample implementation:
$html = <<<'HTML'
<table class="space">
<thead></thead>
<tbody>
<tr>
<td class="marsia">1</td>
<td class="mars">
<div>Mars</div>
</td>
</tr>
<tr>
<td class="earthia">2</td>
<td class="earth">
<div>Earth</div>
</td>
</tr>
<tr>
<td class="earthia">3</td>
</tr>
</tbody>
</table>
HTML;
$doc = new DOMDocument;
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);
$cells = $xpath->query('//table[#class="space"]//tr[count(td) = 2]/td');
$i = 0;
foreach ($cells as $td) {
if (++$i % 2) {
$number = $td->nodeValue;
} else {
$planet = trim($td->textContent);
printf("%d: %s\n", $number, $planet);
}
}
Output
1: Mars
2: Earth
The code above is supposed to be considered as a sample rather than an instruction for practical use, as it is not very scalable. The logic is bound to the fact that the XPath expression selects exactly two cells for each row. In practice, you may want to select the rows, iterate them, and put the extra conditions into the loop, e.g.:
$rows = $xpath->query('//table[#class="space"]//tr');
foreach ($rows as $tr) {
$cells = $xpath->query('.//td', $tr);
if ($cells->length < 2) {
continue;
}
$number = $cells[0]->nodeValue;
$planet = trim($cells[1]->textContent);
printf("%d: %s\n", $number, $planet);
}
DOMXPath::query() is called with an XPath expression relative to the current row ($tr), then checks if the returned DOMNodeList contains at least two cells. The rest of the code is trivial.
You can also use SimpleXML extension, which also supports XPath. But the extension is much less flexible as compared to the DOM extension.
For huge documents, use extensions based on SAX-based parsers such as XMLReader.
I would like to output mysqli query rows, like 4 divs/spans inline and then it goes to next line, outputs next 4 divs/spans and so on. How can I do this ? what should I echo, and/or what kind of operators should I use ?
Actually it isn't a programming issue, but design. You'll need a container with a determined width, and then you can create divs which float aside with the width (%) you need.
Like this:
<div class="container">
{for}
<div class="col-4">echo field</div>
{next}
</div>
And, in your CSS, something like:
.container{width: 1070px}
.col-4{float: left; width: 25%}
You can use a table. Here's my pseudocode
<table>
foreach row in result
echo "
<tr>
<td>result[column1]</td>
<td>result[column2]</td>
... etc
</tr>
"
</table>
each tr will make an inline row and the td's will fill it with data from the query.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
Hello. I have an assignment 9.2 to do and have no idea where to start.
I have made the index.php which allows the user to input the width and height of the table.
Here is the code for that:
<html>
<head>
<title>Assignment 9.2</title>
</head>
<body bgcolor="black" text="white">
<form method="post" action="table.php"
<strong>Please select an integer for the width:</strong>
<input type="text" name="width" size="10">
<br>
<strong>Please select an integer for the height:
<input type="text" name="width" size="10">
<input type="submit" value="Submit">
</form>
</body>
</html>
I do not know where to start on making the table. I do not expect to have this
done for me.. but to simply explain where to start and the php codes I need to use.
Again.. this is for 9.2 which is shown in the picture attached.
Okay, so this is a fairly simple thing to do if you understand how html tables are laid out in code...
HTML table format
The first step is to understand how tables are laid out in html...
3x2 table
For a 3 columned / 2 rowed table the code would look something like this...
Pseudo
opening table tag
opening row tag
cell tag
cell tag
cell tag
closing row tag
opening row tag
cell tag
cell tag
cell tag
closing row tag
closing table tag
HTML
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</table>
I don't know how much you know about html but hopefully that should make sense if not there are a wide variety of resources available that can explain the tags used etc...
PHP Code
At this point we're going to skip the input of width and height (as you already have the code for that) and assume that you've captured them as follows:
$in_width = $_POST['width'];
$in_height = $_POST['height'];
So now we know what the width and height of the table is going to be we can look at how to put them together:
If you look back at the example table code above you'll see that tables are rendered one row at a time in the format:
First row first column
First row second column
First row third column
Second row first column
...and so on...
This might be more clear by looking at the numbers in your screen grab above.
Given that we know how a html table is structured we can determine that we can use two loops* (the second one embedded in the first) to produce the desired output.
(The rows will be the outer loop and the columns will be in the inner loop - see example html code above)
Pseudo code
start table
for each row {
start row
for each column {
print cell
}
end row
}
end table
*You can use any loop you're comfortable with (i.e. for or loop) they do the same thing
If you want to do this yourself, I suggest that you stop reading here. Spoiler follows...
Spoiler
Two while loops
$in_height = $_POST['height']; // Get table height
$in_width = $_POST['width']; // Get table width
$counter = 1; // Start the counter at 1
$temp_width = 0; // Set temporary variable for width(second loop)
echo "<table>"; // Print opening tag for table
while($in_height > 0){
echo "<tr>"; // Print opening tag for row
$temp_width = $in_width; // Set temp_width to width of table
while($temp_width > 0){
echo "<td>$counter</td>"; // Print cell with counter value
++$counter; // Increment counter
--$temp_width; // Decrement temp_width
}
echo "</tr>"; // Print closing tag for row
--$in_height; // Decrement height
}
echo "</table>"; // Print closing tag for table
Two for loops
Just for demonstration purposes...
$in_height = $_POST['height'];
$in_width = $_POST['width'];
$counter = 1;
$temp_width = 0;
$temp_height = 0;
echo "<table>";
for($temp_height = 0; $temp_height < $in_height; $temp_height++) {
echo "<tr>";
for($temp_width = 0; $temp_width < $in_width; $temp_width++){
echo "<td>$counter</td>";
++$counter;
}
echo "</tr>";
}
echo "</table>";
You could also mix and match loops...
I have a SQL pupil's list sorted by classes and this list goes into TCPDF to create a PDF 2 columned list. My issue is that I can't find the way to break the line.
What I know is that a column can have max 59 rows. So, if the next group would not fit they should go to the next column.
The theory would be to check the actual line
$html=$html.'<tr><td width="40"> </td><td width="90"> </td><td width="50"> </td><td width="45"> </td><td width="45"> </td></tr>'; //35
while($classok = mysql_fetch_array($classquery))
{
$classes=$classok['id'];
$classnum=mysql_num_rows(mysql_query("SELECT class_id FROM pupils WHERE class_id=".$classes." AND pupils.torolve=0 and pupils.statusz=1"));
I would like here something that would shift the rows down if the next class would reach more than 59 lines. Like:
$html=$html.'<tr><td></td></tr>';
but I can't put the condition in the right way...
The problem is that the previous group randomly finishes so the next class should start the on the new page.
$headek=$headek.'<b><tr><th>D.O.B.</th><th colspan="2">';
$headek=$headek.$classok['name'].'</th><th colspan="2">';
$headek=$headek.$classok['initname'];
$sum=$sum+$classnum;
$headek=$headek.'('.$classnum.')'.'</th></tr></b>';
$html=$html.strtoupper($headek);
$pupilssql="SELECT pupils.extra_functions, pupils.name, pupils.dateofbirth, pupils.sex, YEAR(pupils.dateofbirth) AS year, MONTH(pupils.dateofbirth) AS month, DAY(pupils.dateofbirth) AS days, pupils.name, pupils.firstname, pupils.class_id FROM pupils, classes WHERE pupils.class_id=classes.id AND pupils.torolve=0 and pupils.statusz=1 AND class_id=".$classes." ORDER BY pupils.name ASC";
$pupilsquery=mysql_query($pupilssql);
while($result = mysql_fetch_array($pupilsquery))
{
etc...
Everything is working well except this column break that I can't put in code... Anyone's help would be appreciated.
They will need to be separate tables. Start a new table for each block of 59 pupils and then use CSS to float the tables so they will stack up next to each other. Or you can be lazy and put those tables inside a table and do EZ formatting (yuck).
Add a variable before your loop: $i = 0;
Iterate it at the beggining of your loop: $i++;
At the end of your loop, use if and modulus to print whatever seperator you want every 59 (or however many) lines: if($i % 59 == 0) echo '<br />';
change <br /> to whatever code you need to seperate the sections