Proclaimed Guru or not, I was actually flummoxed by this as well. But you got it right with your own observation!
... is it possible that because there are two instances of "Import XML..." in the menus (one under File, the other in the dropdown menu in the Structure window) that both are being invoked?
That is indeed correct. xx.item(yy)
retrieves one or more items from a collection. From Marc Autret's blog:
The big secret is that none of the above methods actually returns any element. . . except to understand an 'element' as an object specifier.
What you get is a reference to 'multiple objects', and yes, there are two menu's called "Import XML...". It's kind of hard to persuade InDesign to show that there are two; myMenuAction.length
does not work (it "is" a single element so it has no length), and myMenuAction.constructor.name
shows [Object MenuAction]
-- again, for a single element. However, alert (myMenuAction.name);
finally shows the (un)expected output:
It took a surprising amount of traversing the DOM to find out how to call just one. I opted to located "File" -> "Import XML...", and this is what it takes:
var myMenu = app.menus.item("Main");
var fileMenu = myMenu.menuElements.item("File");
alert (fileMenu.menuItems.everyItem().name);
var myXmlMenu = fileMenu.menuItems.item("Import XML...");
alert (myXmlMenu.name);
myMenuAction = myXmlMenu.associatedMenuAction;
alert (myMenuAction.name);
myMenuAction.invoke();
You can leave out the alerts if you want to use this. Beware that these strings are not in their localizable forms -- this example will only work on InDesign in English, but not when set to use another interface language.
A better way is to avoid calling menus whenever possible. In this case, you probably can safely replace your code with the following:
folder = Folder.myDocuments;
if (File.fs == "Windows")
myFile = folder.openDlg( 'Load XML', "XML files,*.xml;All files:*.*", false);
else
myFile = folder.openDlg( 'Load XML', function(file)
{
return file instanceof Folder ||
(!(file.hidden) && file.name.match(/\.(xml)$/i));
}, false );
}
if (myFile)
xml = app.activeDocument.importXml(myFile);
A few of the advantages are that it's locale independent; you can customize the "Open" dialog to start in another folder (for example, the one where your current document is saved) and use other or more file filters; you can import your XML into the current document, or straight into an existing element (the script version of "Import into Selected Element" in the Import XML dialog); you get a reference to the freshly loaded XML object, so you can immediately post-process it after importing.