Copy link to clipboard
Copied
Hi,
I have three line table coded with XML. I need to check row 2 and 3 XML tag name match with row 1 XML tag name.
Entire Line 1 is coded by a single line XML tag name. Though we can take name from row 2 for now. I have a huge list for every header name relevant XML tag name.
I tried to get every tag name separated by tab. But it throws wrong tag name. Please suggest. Thanks.
var para=app.selection[0];
var lines=para.contents.split('\r');
var no_of_lines = lines.length;
for(line = 0; line < no_of_lines; line++)
{
var x = lines[line].split('\t');
var mySelWords = x.length;
for(i=0;i<x.length;i++){
alert(x+" ------> "+para.lines[line].words.associatedXMLElements[0].markupTag.name)
}
}
I have attached the sample file.
Thanks,
K
Message was edited by: kk kk
var main = function() {
var sel = app.properties.selection, tf, ps, ln, headers = {count:0}, n = 0, tableHeader, lines,errors = [], check;
if ( !sel || sel.length!=1 || !(sel[0] instanceof TextFrame) ) return;
tf = sel[0];
var xe = tf.properties.associatedXMLElement;
if ( !xe ) return;
ps = xe.xmlContent;
tableHeading = xe.evaluateXPathExpression ( "//table_heading" );
if ( !tableHeading.length ) return;
ln = tableHeading[0].xmlContent.contents.split("\t");
n = ln.length;
while ( n-- ) {
headers[ln
] = 1; headers.count+=1;
}
lines = ps.lines;
n = lines.length;
while ( n-- ) {
if ( n==0 ) break;
ln = lines
; check = checkLine ( ln, headers );
if ( check.length ) {
errors.push ( "Line:"+(n+1)+":\r\t"+check.join("\r\t-") );
}
}
alert(errors.length? errors.join("\r") : "Seems fine");
}
function checkLine ( line, headers ) {
var xes = line.associatedXMLElements, n = xes.length, lineTagCount = 0, nXe, missing = [], xeName;
while ( n-- ) {
nXe = xes
; xeName = nXe.markupTag.name;
if ( xeName=="copy_frame" ) continue;
if ( headers[xeName] ) {
lineTagCount+=1;
}
else {
missing.push ( xeName );
}
}
return missing;
}
var u;
app.doScript ( "main()",u,u,UndoModes.ENTIRE_SCRIPT, "The Script" );
Copy link to clipboard
Copied
Hi,
I have three line table coded with XML. I need to check row 2 and 3 XML tag name match with row 1 XML tag name.
Entire Line 1 is coded by a single line XML tag name. Though we can take name from row 2 for now. I have a huge list for every header name relevant XML tag name.
I tried to get every tag name separated by tab. But it throws wrong tag name. Please suggest. Thanks.
var para=app.selection[0];
var lines=para.contents.split('\r');
var no_of_lines = lines.length;
for(line = 0; line < no_of_lines; line++)
{
var x = lines[line].split('\t');
var mySelWords = x.length;
for(i=0;i<x.length;i++){
alert(x+" ------> "+para.lines[line].words.associatedXMLElements[0].markupTag.name)
}
}
I have attached the sample file.
Thanks,
K
Message was edited by: kk kk
var main = function() {
var sel = app.properties.selection, tf, ps, ln, headers = {count:0}, n = 0, tableHeader, lines,errors = [], check;
if ( !sel || sel.length!=1 || !(sel[0] instanceof TextFrame) ) return;
tf = sel[0];
var xe = tf.properties.associatedXMLElement;
if ( !xe ) return;
ps = xe.xmlContent;
tableHeading = xe.evaluateXPathExpression ( "//table_heading" );
if ( !tableHeading.length ) return;
ln = tableHeading[0].xmlContent.contents.split("\t");
n = ln.length;
while ( n-- ) {
headers[ln
] = 1; headers.count+=1;
}
lines = ps.lines;
n = lines.length;
while ( n-- ) {
if ( n==0 ) break;
ln = lines
; check = checkLine ( ln, headers );
if ( check.length ) {
errors.push ( "Line:"+(n+1)+":\r\t"+check.join("\r\t-") );
}
}
alert(errors.length? errors.join("\r") : "Seems fine");
}
function checkLine ( line, headers ) {
var xes = line.associatedXMLElements, n = xes.length, lineTagCount = 0, nXe, missing = [], xeName;
while ( n-- ) {
nXe = xes
; xeName = nXe.markupTag.name;
if ( xeName=="copy_frame" ) continue;
if ( headers[xeName] ) {
lineTagCount+=1;
}
else {
missing.push ( xeName );
}
}
return missing;
}
var u;
app.doScript ( "main()",u,u,UndoModes.ENTIRE_SCRIPT, "The Script" );
Copy link to clipboard
Copied
Hi,
Could you please anyone suggest if you know anything related to my question? It is very helpful to finish my script.
Thanks,
K
Copy link to clipboard
Copied
You assume no difference between the tab separated line ('x') and the 'words' in that same line 'para.lines[line].words[..]'. They are clearly not the same; several of your tab contents contain more than a single word.
Copy link to clipboard
Copied
Hi Jongware,
Thanks for your reply. Yes I aware the count of each word length between the tab separated is diffeerent. I thought in between the tab the word is coding by only one tag. So even it have two or three words, the first and second word contain same tag.
Thanks,
K
Copy link to clipboard
Copied
var main = function() {
var sel = app.properties.selection, tf, ps, ln, headers = {count:0}, n = 0, tableHeader, lines,errors = [], check;
if ( !sel || sel.length!=1 || !(sel[0] instanceof TextFrame) ) return;
tf = sel[0];
var xe = tf.properties.associatedXMLElement;
if ( !xe ) return;
ps = xe.xmlContent;
tableHeading = xe.evaluateXPathExpression ( "//table_heading" );
if ( !tableHeading.length ) return;
ln = tableHeading[0].xmlContent.contents.split("\t");
n = ln.length;
while ( n-- ) {
headers[ln
] = 1; headers.count+=1;
}
lines = ps.lines;
n = lines.length;
while ( n-- ) {
if ( n==0 ) break;
ln = lines
; check = checkLine ( ln, headers );
if ( check.length ) {
errors.push ( "Line:"+(n+1)+":\r\t"+check.join("\r\t-") );
}
}
alert(errors.length? errors.join("\r") : "Seems fine");
}
function checkLine ( line, headers ) {
var xes = line.associatedXMLElements, n = xes.length, lineTagCount = 0, nXe, missing = [], xeName;
while ( n-- ) {
nXe = xes
; xeName = nXe.markupTag.name;
if ( xeName=="copy_frame" ) continue;
if ( headers[xeName] ) {
lineTagCount+=1;
}
else {
missing.push ( xeName );
}
}
return missing;
}
var u;
app.doScript ( "main()",u,u,UndoModes.ENTIRE_SCRIPT, "The Script" );
Copy link to clipboard
Copied
Hi Loic,
It almost over, really awesome script. If possible please help me with one more thing.
The real requirement is, I need to get the row 1 heading tag and check the rest of rows tag will match with that. But the row 1 will come with only one tag. The list of tag name is something like this,
Table header | Attribute Tags |
Item # | sku |
Product Dimensions | product_dimensions |
Color | color |
Quantity | quantity |
List Price | list_price |
Pen Style | pen_style |
Nib Type | nib_type |
Nib Size | nib_size |
Ink Color | ink_color |
Description | description |
Is it possible include this with your script.
Thanks,
K
Copy link to clipboard
Copied
For example,
Row 1 column 2 content is = Description and releavent tag name is description
then
Row 2 column 2 contentAtomic Fossball Table should be description
Row 2 column 2 content Fossballs Table should be description
Copy link to clipboard
Copied
I think that in your case you need a correspondance table. here I use a simple object. I will later place the "header" content and retrieve the expected xml tag name accordingly (see corrs object):
var main = function() {
var sel = app.properties.selection, tf, ps, ln, headers = {count:0}, n = 0, tableHeader, lines,errors = [], check,
corrs= {
"Item #":"sku",
};
if ( !sel || sel.length!=1 || !(sel[0] instanceof TextFrame) ) return;
tf = sel[0];
var xe = tf.properties.associatedXMLElement;
if ( !xe ) return;
ps = xe.xmlContent;
tableHeading = xe.evaluateXPathExpression ( "//table_heading" );
if ( !tableHeading.length ) return;
ln = tableHeading[0].xmlContent.contents.split("\t");
n = ln.length;
while ( n-- ) {
headers[corrs[ln
]] = 1; headers.count+=1;
}
lines = ps.lines;
n = lines.length;
while ( n-- ) {
if ( n==0 ) break;
ln = lines
; check = checkLine ( ln, headers );
if ( check.length ) {
errors.push ( "Line:"+(n+1)+":\r\t"+check.join("\r\t-") );
}
}
alert(errors.length? errors.join("\r") : "Seems fine");
}
function checkLine ( line, headers ) {
var xes = line.associatedXMLElements, n = xes.length, lineTagCount = 0, nXe, missing = [], xeName;
while ( n-- ) {
nXe = xes
; xeName = nXe.markupTag.name;
if ( xeName=="copy_frame" ) continue;
if ( headers[xeName] ) {
lineTagCount+=1;
}
else {
missing.push ( xeName );
}
}
return missing;
}
var u;
app.doScript ( "main()",u,u,UndoModes.ENTIRE_SCRIPT, "The Script" );
Copy link to clipboard
Copied
Hi Lioc,
Thank you for considering my request. I added all the tag names in the corrs but I am afraid this will searching by rows not by columns . So that even if I change any tag as wrongly it alerts as seems fine.
corrs= {
"Item #":"sku",
"Description":"description",
"Brand":"brand",
"Product Dimensions":"product_dimensions",
"Quantity":"quantity",
"List Price":"list_price"
};
Thanks,
K
Copy link to clipboard
Copied
It seems it take line by line for checking, instead we need to take every column in account.
Copy link to clipboard
Copied
Let's try it this way:
var main = function() {
var sel = app.properties.selection, tf, ps, ln, headers = {count:0}, n = 0, tableHeader, lines,errors = [], check,
corrs= {
"Item #":"sku",
"Description":"description",
"Brand":"brand",
"Product Dimensions":"product_dimensions",
"Quantity":"quantity",
"List Price":"list_price"
};
if ( !sel || sel.length!=1 || !(sel[0] instanceof TextFrame) ) return;
tf = sel[0];
var xe = tf.properties.associatedXMLElement;
if ( !xe ) return;
ps = xe.xmlContent;
tableHeading = xe.evaluateXPathExpression ( "//table_heading" );
if ( !tableHeading.length ) return;
ln = tableHeading[0].xmlContent.contents.split("\t");
n = ln.length;
while ( n-- ) {
headers[corrs[ln
]] = 0; headers.count+=1;
}
checkContents ( ps , headers )
}
function checkContents ( story , headers ) {
var xes = story.associatedXMLElement.evaluateXPathExpression ( "//*[name(./..)='copy_frame']" ).reverse(),
currIndex, currNumber, n = xes.length, i = 0, nXe, xEc, xEl, xeName, data = {}, lnCount = story.lines.length-1;
while ( i<n ) {
nXe = xes;
xEc = nXe.xmlContent;
xEl = xEc.lines[0];
if ( xEl.index != 0 ) {
if ( !currNumber ) {
currNumber = 2;
currIndex = xEl.index;
}
else if (currIndex!=xEl.index ) {
currNumber++;
currIndex = xEl.index;
}
xeName = nXe.markupTag.name;
if ( xeName!="copy_frame" ) {
(typeof headers[xeName] != "undefined") && headers[xeName]=headers[xeName]+1;
}
}
i++;
}
for (prop in headers ) {
if ( prop != "count" && headers[prop]!=lnCount) {
alert("Something is wrong");
return;
}
}
alert("all good");
}
var u;
app.doScript ( "main()",u,u,UndoModes.ENTIRE_SCRIPT, "The Script" );
Copy link to clipboard
Copied
Hello Loic,
THANK YOU SO MUCH.
It is working really well except one small thing, it is commonly said "Something is wrong". If it show the error lines like your previous scripts then it is phenomenal.
Thanks,
K
Copy link to clipboard
Copied
I can imagine but the second approach is more generic hence the lack of details. I won't have time to pursue this but you have the main idea now
on a plus note, it seems the data was generated from some kind of data management tool. The table structure can be saw in the data. In that case, you could have tried to turn those tables into indesign own xml syntax for tables. You will have a quick way then to ensure everything is on teh right spot and use cell/table styles for data representation.
Copy link to clipboard
Copied
Hi Loic,
Thanks for pointing me with the table structure in the data management tool. Yes the operator pulling data from external plugin.
Sorry I ate most of you time today. But it is a learning experience for me because this is the first project I am working with XML.
Besides this, I have more work with this script like excluding subheading if anything come in between the row.. some text frames contains paragraph and then it follow with table.. like that..
Anyhow a big THANKS again for your contribution with this thread..
I am really happy with the solution found here.
Thanks,
K