Copy link to clipboard
Copied
Hi All, I have a script that builds and XML object of a FrameMaker document's structure. I use this map in subsequent functions that need to query the document's element/attribute structure using ExtendScript's xpath function. This is faster than traversing the document's structure multiple times.
Now the client has a large document--almost 700 pages--that has tons of tables. The script uses recursion to traverse and build the XML object map and I think that is where it is failing. I am not sure there is a good solution, but I wanted to put it out there in case you wireheads have any ideas. Thanks.
#target framemaker
var GS_XMNT = GS_XMNT || {};
GS_XMNT.version = "Version 0.1b November 18, 2024";
GS_XMNT.file = $.fileName;
GS_XMNT.main = function (doc, element) {
var xmlMap;
if (doc.ObjectValid () === 1) {
if (element.ObjectValid () === 1) {
xmlMap = GS_XMNT.getXmlMap (doc, element);
alert (xmlMap.hasComplexContent ());
return (xmlMap);
}
}
};
GS_XMNT.getXmlMap = function (doc, element) {
var xmlMap;
if (element.ObjectValid () === 1) {
textList = element.GetText (Constants.FTI_ElementBegin);
if (textList.length > 1) {
xmlMap = GS_XMNT.makeNode (element, "");
GS_XMNT.makeXmlMap (element, 0, xmlMap, doc, {});
}
else {
xmlMap = GS_XMNT.makeNode (element, GS_XMNT.getText (element, doc));
}
}
return xmlMap;
};
GS_XMNT.getElementText = function (element, doc) {
var text = "";
if (!element.FirstChildElement.ObjectValid ()) {
text = GS_XMNT.getText (element, doc);
}
return text;
};
GS_XMNT.getDocById = function (docId) {
var doc = app.FirstOpenDoc;
while (doc.ObjectValid ()) {
if (doc.id === docId) {
return doc;
}
doc = doc.NextOpenDocInSession;
}
};
GS_XMNT.makeXmlMap = function (element, level, xmlMap, doc, currNode) {
var node, text, element2;
if (!element.ElementDef.ElementDefIsText ()) {
if (level > 0) {
text = GS_XMNT.getElementText (element, doc);
node = GS_XMNT.makeNode (element, text);
node = GS_XMNT.addNode (node, xmlMap, level);
currNode.node = node;
}
}
else {
currNode.node = node;
/* text = GS_XMNT.getElementText (element, doc);
try {
node = new XML (text);
node = GS_XMNT.addNode (node, xmlMap, level);
}
catch (e) {
alert (e);
} */
}
element2 = element.FirstChildElement;
while(element2.ObjectValid () === 1) {
GS_XMNT.makeXmlMap (element2, level + 1, xmlMap, doc, currNode);
element2 = element2.NextSiblingElement;
}
};
GS_XMNT.addNode = function (node, xmlMap, level) {
var i, parent;
parent = xmlMap;
for (i = 1; i < level; i += 1) {
parent = parent.child (parent.children ().length () - 1);
}
parent.appendChild (node);
return node;
};
GS_XMNT.makeNode = function (element) {
var node, attrList, count, i, attrValue;
node = <{element.ElementDef.Name} unique={element.Unique}/>;
attrList = element.Attributes;
count = attrList.length;
for (i = 0; i < count; i += 1) {
attrValue = attrList[i].values[0] ? attrList[i].values[0] : "";
if (attrValue !== "") {
node.@[attrList[i].name] = attrValue;
}
}
return node;
};
GS_XMNT.getText = function (textObj, doc) {
// Gets the text from the text object.
var text = "", textItems, count, i;
return text;
// Get a list of the strings in the text object or text range.
if (textObj.constructor.name !== "TextRange") {
textItems = textObj.GetText (Constants.FTI_String);
}
else {
textItems = doc.GetTextForRange (textObj, Constants.FTI_String);
}
// Concatenate the strings.
count = textItems.len;
for (var i = 0; i < count; i += 1) {
text += (textItems[i].sdata);
}
return GS_XMNT.cleanText (text); // Return the text
};
GS_XMNT.cleanText = function (text) {
var regex;
// Non-standard spaces to regular spaces.
regex = /[\x08-\x14\x20]+/g;
if (regex.test (text) === true) {
text = text.replace (regex, " ");
}
/* // Delete leading and trailing spaces.
regex = /(?:^[\x08-\x14\x20]+|[\x08-\x14\x20:]+$)/g;
if (regex.test (text) === true) {
text = text.replace (regex, "");
} */
return text;
};
GS_XMNT.main (app.ActiveDoc, app.ActiveDoc.MainFlowInDoc.HighestLevelElement);
Copy link to clipboard
Copied
Hi Rick,
I don't have much time right now, so I can't take a closer look at the script.
But maybe my experience from last year will help you.
Passing larger XML to a function always caused a crash for me. I then changed it and accessed the global XML object DIRECTLY in the function. That worked. Give it a try.
Have a nice weekend.
Klaus
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more