Trying to find XPath for multiple TDs - xpath

I want to extract the Address for specific Numbers (the first TD) of this table. The only unique identifier for the table is the H3.
Here is the code for the table:
<table width="95%" cellpadding=5 cellspacing=0 border=1>
<tr><td colspan="4"><h3>The list</td></tr>
<tr>
<td>Number</td><td>First Name</td>
<td>Last Name</td><td>Address</td>
</tr>
I have tried:
//table[#h3=’See this now’]/’tr/td[87] and td[107] and td[116]
I am new to xpath, and programming in general. It's pretty fun, but would love to be able to figure this one out!! Appreciate any help :D

First, your HTML is wrong.
You did not close your Table element.
You did not close your H3 element.
You must enclose your attributes in quotes.
<table width="95%" cellpadding="5" cellspacing="0" border="1">
<tr>
<td colspan="4">
<h3>The list</h3>
</td>
</tr>
<tr>
<td>Number</td>
<td>First Name</td>
<td>Last Name</td>
<td>Address</td>
</tr>
</table>
Once you have fixed the formatting of your XHTML. You can traverse the document tree.
XPATH
Any table, with any td that has a h3.
//table//td/h3
Will return
<h3>The list</h3>
For the number
//table//tr[2]/td[1] <-- any table, the second tr element in this table, the first td in that second tr
Will return
<td>Number</td>
So if we add multiple tables to a document and you want to find multiple results for each element in any table, this is quite simple. Say we have a XHTML document with many tables inside a parent element, for example 'root' element.
<root>
<table width="95%" cellpadding="5" cellspacing="0" border="1">
<tr>
<td colspan="4">
<h3>The list</h3>
</td>
</tr>
<tr>
<td>123</td>
<td>First Name</td>
<td>Last Name</td>
<td>Address</td>
</tr>
</table>
<table width="95%" cellpadding="5" cellspacing="0" border="1">
<tr>
<td colspan="4">
<h3>The list</h3>
</td>
</tr>
<tr>
<td>456</td>
<td>First Name</td>
<td>Last Name</td>
<td>Address</td>
</tr>
</table>
<table width="95%" cellpadding="5" cellspacing="0" border="1">
<tr>
<td colspan="4">
<h3>The list</h3>
</td>
</tr>
<tr>
<td>789</td>
<td>First Name</td>
<td>Last Name</td>
<td>Address</td>
</tr>
</table>
</root>
We can extract the number of the first table data in each second row in every table using the following XPATH expression:
//table/tr[2]/td[1]
This will give us the result of
<td>123</td>
-----------------------
<td>456</td>
-----------------------
<td>789</td>
Now, say we have several tables, but only one table is very important to us, the table must have a H3 element, no other element is important to us, and if this table has a H3 element, we want to extract the second rows first td.
<root>
<table width="95%" cellpadding="5" cellspacing="0" border="1">
<tr>
<td colspan="4">
<h4>Ignore me!</h4>
</td>
</tr>
<tr>
<td>1164961564896</td>
<td>First Name</td>
<td>Last Name</td>
<td>Address</td>
</tr>
</table>
<table width="95%" cellpadding="5" cellspacing="0" border="1">
<tr>
<td colspan="4">
<h1>I'm not interesting</h1>
</td>
</tr>
<tr>
<td>456456466465</td>
<td>First Name</td>
<td>Last Name</td>
<td>Address</td>
</tr>
</table>
<table width="95%" cellpadding="5" cellspacing="0" border="1">
<tr>
<td colspan="4">
<h3>IM THE IMPORTANT TABLE!</h3>
</td>
</tr>
<tr>
<td>123456789</td>
<td>First Name</td>
<td>Last Name</td>
<td>Address</td>
</tr>
</table>
</root>
We can acomplish this by traversing back up the tree if we are successful in finding the H3 element, then go to the next tr.
//table//h3/../../../tr/td[1]
Will return
<td colspan="4">
<h3>IM THE IMPORTANT TABLE!</h3>
</td>
-----------------------
<td>123456789</td>

Related

Why Xpath 3.0 works, but Xquery 3.0 doesn't work with the same expression

I launched Xpath in Oxygen. In Xpath 3.0 found what i need but in Xquery 3.0 doesn't find.
This is my Xpath expression
//table[tbody/tr/th/p[contains(text(), 'All Water System Contacts')]]/tbody/tr[3]/td[1]
This is my xml code
I put part code.
<table border="1" cellpadding="1" cellspacing="1" summary="." width="640">
<tbody>
<tr>
<th colspan="3">
<p>All Water System Contacts </p></th>
</tr>
<tr>
<th>Type</th>
<th>Contact</th>
<th>Communication</th>
</tr>
<tr>
<td align="center">AC - Administrative Contact - GENERAL MANAGER </td>
<td align="center">GRANT, JOHN, W <br/> PO BOX 869<br/> BIG SPRING, TX 79721-0869 </td>
<td align="center">
<table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse"
width="100%">
<tbody>
<tr>
<th><b>Electronic Type</b></th>
<th><b>Value</b></th>
</tr>
</tbody>
</table>
<table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse"
width="100%">
<tbody>
<tr>
<th><b>Phone Type</b></th>
<th><b>Value</b></th>
</tr>
<tr>
<td align="center">BUS - Business</td>
<td align="center">432-267-6341 </td>
</tr>
<tr>
<td align="center">FAX - Facsimile</td>
<td align="center">432-267-3121 </td>
</tr>
<tr>
<td align="center">BUS - Business</td>
<td align="center">432-267-6070 </td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td align="center">OW - Owner </td>
<td align="center">COLORADO RIVER MUNICIPAL WATER DISTRICT <br/> PO BOX 869<br/> BIG
SPRING, TX 79721-0869 </td>
<td align="center"> </td>
</tr>
</tbody>
</table>
I tried different functions.
I don't know why it doesn't work and what difference
Please help me.
I suspect your real, complete input has an XHTML default namespace declaration xmlns="http://www.w3.org/1999/xhtml" and in oXygen for XPath you have the setting enabled to "use the default namespace of the root element" so your path works with XPath out of the box while for XQuery you need to make sure you explicitly set
declare default element namespace 'http://www.w3.org/1999/xhtml';
in the prolog of your XQuery file or code sample.

how to avoid double borders in HTML graphviz

I have the following simple
Node in a graph:
digraph "graph.svg" {
graph [bgcolor="#333333" fontcolor=white fontname=Helvetica fontsize=16 label="Title" rankdir=TB]
0 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="2" BGCOLOR="#006699">
<TR>
<TD COLSPAN="2">Node Titel</TD>
</TR>
<TR>
<TD COLSPAN="2">Sieve</TD>
</TR>
<TR>
<TD CELLPADDING="0">
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" BGCOLOR="#006699">
<TR>
<TD BORDER="1">in 1</TD>
</TR>
<TR>
<TD BORDER="1">in 2</TD>
</TR>
</TABLE>
</TD>
<TD CELLPADDING="0">
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" BGCOLOR="#006699">
<TR>
<TD BORDER="1">out 1</TD>
</TR>
<TR>
<TD BORDER="1">out 2</TD>
</TR>
<TR>
<TD BORDER="1">out 3</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>> shape=plaintext]
}
Which produces this output:
How can I make the borders align such that no double borders appear anywhere between the nested tables?
I managed to fiddle around with the CELLSPADING=-1
but I don't think that is the way to go?
I cannot use the COLSPAN option because the inputs and outputs ports are variable in size, that's why I solved this with a nested table for both input and output cells.
you were near there
digraph "graph.svg" {
graph [bgcolor="#333333" fontcolor=white fontname=Helvetica fontsize=16 label="Title" rankdir=TB]
0 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="2" BGCOLOR="#006699">
<TR>
<TD COLSPAN="2">Node Titel</TD>
</TR>
<TR>
<TD COLSPAN="2">Sieve</TD>
</TR>
<TR>
<TD CELLPADDING="0" BORDER="0">
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" BGCOLOR="#006699">
<TR>
<TD BORDER="1">in 1</TD>
</TR>
<TR>
<TD BORDER="1">in 2</TD>
</TR>
</TABLE>
</TD>
<TD CELLPADDING="0" BORDER="0">
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" BGCOLOR="#006699">
<TR>
<TD BORDER="1">out 1</TD>
</TR>
<TR>
<TD BORDER="1">out 2</TD>
</TR>
<TR>
<TD BORDER="1">out 3</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>> shape=plaintext]
}

Mailchimp edit table cell background color

Is there any logical way to change the background colour for a table cell in a repeatable region in mailchimp? Here is my code, I don't see any options in mailchimp with the custom template build.
<table width="100%" cellspacing="20" mc:repeatable="product" mc:variant="content1">
<tbody>
<tr>
<td align="center" bgcolor="#ff0000" valign="middle" mc:edit="playlist"><h2>Playlist</h2>
<h3>Check out this playlist!</h3>
<h4>FOLLOW</h4></td>
</tr>
</tbody>
</table>
I came across a similar issue today. Here's a possible solution:
<table width="100%" cellspacing="20" mc:repeatable="product" mc:variant="red">
<tbody>
<tr>
<td align="center" bgcolor="#ff0000" valign="middle" mc:edit="playlist">
<h2>Playlist</h2>
<h3>Check out this playlist!</h3>
<h4>FOLLOW</h4>
</td>
</tr>
</tbody>
</table>
<table width="100%" cellspacing="20" mc:repeatable="product" mc:variant="green">
<tbody>
<tr>
<td align="center" bgcolor="#00ff00" valign="middle" mc:edit="playlist">
<h2>Playlist</h2>
<h3>Check out this playlist!</h3>
<h4>FOLLOW</h4>
</td>
</tr>
</tbody>
</table>
<table width="100%" cellspacing="20" mc:repeatable="product" mc:variant="blue">
<tbody>
<tr>
<td align="center" bgcolor="#0000ff" valign="middle" mc:edit="playlist">
<h2>Playlist</h2>
<h3>Check out this playlist!</h3>
<h4>FOLLOW</h4>
</td>
</tr>
</tbody>
</table>
When you've imported this into your template, create a campaign and on the design page you'll have a dropdown with the different colour options. Make any h2s, h3s etc editable by adding mc:edit.

Optimal XPath Query for processing the sample HTML fragment

I have a feed that outputs HTML. The following segment is part of the output
<div class="leftnav">
<table border="0" cols="2">
<tr>
<td colspan="2" class="topline"><span style="font-size: 1px"> </span></td>
</tr>
<tr>
<td colspan="2"><span class="bold">Article Cat1 </span></td>
</tr>
<tr>
<td class="date" colspan="2">
ArticleTitle1</td>
</tr>
<tr>
<td width="20"></td>
<td class="date">
ArticleLink1
</td>
</tr>
<tr>
<td colspan="2" class="topline"><span style="font-size: 1px"> </span></td>
</tr>
<tr>
<td colspan="2"><span class="bold">Article Cat2 </span></td>
</tr>
<tr>
<td class="date" colspan="2">
ArticleTitle2</td>
</tr>
<tr>
<td width="20"></td>
<td class="date">
ArticleLink2
</td>
</tr>
</table>
</div>
I want to process above segment using XPATH so that output looks like this
Article Cat1
ArticleTitle1
ArticleLink1 Article Cat2
ArticleTitle2
ArticleLink2
What is the optimal XPATH that will produce the desired output? I tried //div[#class="leftnav"]/table/tr but this gives all the TR elements. I want to skip the first TR element so that I can get the output in the format I described above.
//div[#class="leftnav"]/table/tr[position() > 1]
Try the above
Stupid simple way:
substring-after(normalize-space(string(//*:div)), normalize-space(string(//*:div/*:table/*[1])))
Result: "Article Cat1 ArticleTitle1 ArticleLink1 nbsp Article Cat2 ArticleTitle2 ArticleLink2"
I don't know why, but (position() > 1) doesn't work in my environment, so I've used strings instead.

How to create a two column email newsletter

I am trying to create a two column email flyer but I'm having trouble with the coding as Outlook hates CSS.
I'm using tables to keep it as simple as possible but I want two separate tables on the left and the right so I can add data into it as I wish.
I tried using float left and right on the two tables but Outlook ignores this style.
I know the two grey tables at the bottom are each in their own separate "holder" tables but this is so I can duplicate the grey "data" tables for when I add new articles.
<table class="all" width="auto" height="auto" border="0" cellspacing="0"><tr><td height="504">
<table width="750" height="140" border="0" cellspacing="0">
<tr>
<td width="200" valign="bottom" bgcolor="#E6E6E6"> </td>
<td width="345" align="center" valign="bottom" bgcolor="#E6E6E6"> </td>
<td width="152" align="center" valign="bottom" bgcolor="#E6E6E6"> </td>
<td width="45" align="center" valign="bottom" bgcolor="#E6E6E6"> </td>
</tr>
<tr>
<td width="200" valign="bottom" bgcolor="#E6E6E6"> </td>
<td align="center" valign="bottom" bgcolor="#E6E6E6"><font color="#111111" face="Arial Narrow" size="+2">DECEMBER NEWSLETTER</font></td>
<td width="152" align="center" valign="bottom" bgcolor="#E6E6E6"><font size="2"><strong>#4 - <span class="orange">04.12.13</span></strong></font></td>
<td width="45" align="center" valign="bottom" bgcolor="#E6E6E6"> </td>
</tr>
</table>
<table width="750" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="75" height="50" bgcolor="#E6E6E6" scope="row"> </td>
<td width="600" rowspan="2" scope="row"><img src="http://placehold.it/600x200"/></td>
<td width="75" bgcolor="#E6E6E6" scope="row"> </td>
</tr>
<tr>
<td width="75" height="81" scope="row"> </td>
<td scope="row"> </td>
</tr>
</table>
<table class="holder" width="750" border="0" cellspacing="0" cellpadding="0">
<tr>
<td valign="top" scope="row">
<table class="inlinetableleft" width="360">
<tr>
<td width="371" align="left">
<!------------LEFT COLUMN------------------>
<table width="360" border="0" cellspacing="0" cellpadding="0">
<tr>
<th height="103" colspan="4" align="left" valign="middle" bgcolor="#CCCCCC" scope="row"> </th>
</tr>
</table>
<!--------------LEFT COLUMN END------------->
</td>
</tr>
</table>
<table class="inlinetableright" width="360">
<tr>
<td align="left">
<!------------RIGHT COLUMN------------------>
<table width="360" border="0" cellspacing="0" cellpadding="0">
<tr>
<td height="106" align="left" bgcolor="#CCCCCC" scope="row"> </td>
</tr>
</table>
<!-----------RIGHT COLUMN END-------------->
</td></tr>
</table>
</td>
</tr>
</table>
Here is a fiddle of my newsletter so far, it's the bottom two grey tables that I want to be side by side.
Fiddle
For HTML emails, nested tables are your friend :)
JSFiddle
Note: the border around the table is just to show you where the tables are.
<table border="0" width="600" cellpadding="0" cellspacing="0" align="center">
<tr>
<td colspan="2">
header content here
</td>
</tr>
<tr>
<td width="300">
<table border="0" width="300" cellpadding="1" cellspacing="0" align="left">
<tr>
<td>Left Content</td>
</tr>
</table>
</td>
<td width="300">
<table border="0" width="300" cellpadding="1" cellspacing="0" align="left">
<tr>
<td>Right content</td>
</tr>
</table>
</td>
</tr>
</table>

Resources