Community Tip - Have a PTC product question you need answered fast? Chances are someone has asked it before. Learn about the community search. X
I have what may be an easy question here about document manipulation using the DOM and AOM and executing Arbortext commands.
To briefly describe my goal: I'm trying to add a namespace declaration to all XML files that are referenced in a .dita file (ditamap file) via a custom Arbortext menu tool (javascript). This ditamap contains XML elements that describe the URI locations of XML files.
Since the ditamap file is what is opened in Arbortext, I'm trying to find a way to set the DOM/AOM to point to the URI location of the individual XML files referenced in the ditamap. This way I can run a simple Arbortext command on them to add the namespace to each XML file.
Javascript code sample below:
AddNamespace function() {
var actDoc = Application.activeDocument; // set the DOM to the active document open in Arbortext
var uri = actDoc.getElementsByAttribute("XMLfileURI", "", 0); // grab XML file URI's and store in array
var i;
for (i = 0; i < uri.length; i++) {
var curDoc = Application.openDocument(uri); // open the document at the URI
Acl.execute('modify_tag root xmlns:mine="http://myCustomNamespacehere.com"'); //add namespace declaration to "root" element
curDoc.save(); //save the document
}
Right now, the "modify_tag" Arbortext command is breaking because it is still running the command on the ditamap file (the Application.activeDocument). Is it possible to point activeDocument to the newly opened curDoc document? If that isn't possible what would I need to do to run the Arbortext command on a document that isn't the current Application.activeDocument?
Thank you in advance.
Solved! Go to Solution.
Before you execute the modify_tag command you need to call current_doc(docId), where docId is the document ID of the doc you want to set as the current document. In this case it should be the value of curDoc.aclId. aclId is a member of the ADocument interface.
Before you execute the modify_tag command you need to call current_doc(docId), where docId is the document ID of the doc you want to set as the current document. In this case it should be the value of curDoc.aclId. aclId is a member of the ADocument interface.
Thanks for the reply Brian.
I tried out your code, I'm grabbing the right docID with aclId but I think something is going wrong with my modify_tag command.
I'm getting an error saying "The cursor is not near tag "'root'" (root is the element I'm trying to add the namespace to.)
Is there a caveat about using modify_tag? If so would there be a better command to use?
My new code:
var curDoc = Application.openDocument(uri);
var docId = curDoc.aclId;
Acl.func("current_doc", docId);
Acl.execute('modify_tag root xmlns:mine="http://myCustomNamespacehere.com"');
curDoc.save();
I'm not sure if it makes a difference or not, but according to the documentation for the modify_tag command, it looks like you need to precede the tag name with either the -local or -global switch, like this:
modify_tag -local root xmlns:mine='http://mycustomnamespacehere.com/'
If you use -global, that command will change the xmlns:mine attribute on every "root" tag in the entire document. Using -local restricts the change to the "current instance of the tag", which (to me, at least) seems to indicate that the cursor needs to be located in the root tag you want to change. So I would try something like this:
// Get the Element or Node object for your root tag, then...
var rootOid = rootNode.firstOID;
Acl.eval("goto_oid('" + rootOID + "')"); // Take note of the single & double quotes here
// If the Acl.func() methods are available in JavaScript, replace that last line with this...
Acl.func("goto_oid", rootOID);
Then you should be able to execute the modify_tag command.
This worked:
Acl.func("current_doc", docId);
var rootNode = Acl.func("oid_first_tag"); //retrieve OID for the root element
Acl.func("goto_oid", rootNode, "-2"); //set cursor to specified OID with a depth of -2 to set the cursor immediately before the start tag.
Acl.execute('modify_tag root xmlns:mine="http://www.mycustomNamespace.com"');
As for the modify_tag -local/-global options, it looks like -local is the default option, so I kept that omitted. I'm adding the namespace to just the root element anyway, so setting it to -global wouldn't have been helpful.
Thanks for the help!!
Glad it works. You shouldn't need the -2 parameter in the call to goto_oid, since the default is to place the cursor just inside the tag, which would allow that to be the "current" tag for purposes of the modify_tag command. Of course you're using oid_first_tag(), which may (?) give a different result from oid_root(), which is what I always use.
Come across another problem, my root element may not always be of name "root". Since the modify_text command only takes in 1 element name, is there another Arbortext command/function you know of that I can pass the OID to and add the namespace?
Change the modify_tag line to this:
Acl.execute('modify_tag ' . oid_name(oid_root()) . ' xmlns:mine="http://www.mycustomNamespace.com"');
Got it:
Acl.func("current_doc", docId);
var rootNode = Acl.func("oid_first_tag");
var rootName = Acl.func("oid_name", rootNode);
Acl.func("goto_oid", rootNode);
Acl.execute('modify_tag ' + rootName + ' xmlns:mine="http://www.mycustomNS.com"');
Arbortext was throwing errors so I had to call oid_name(oid_root()) outside of the execute statement and pass it in via variable. Thanks again!