Delete xml element not used in document
Copy link to clipboard
Copied
Hi,
If you have a number of texts tagged with an xml element and then delete the text, the element still exist in the structure.
You can see the element still connected to a text, by the blue diamond on the element symbol.
But i want do delete the elements that have no connection to texts, but cant find the right property to look for.
In Java script CS4.
Anyone knows?
/Mikael
Copy link to clipboard
Copied
I'm having troubles getting the blue diamond (Strange -- I seem to have no problem with that at work!)
But: perhaps you can test xmlItems[xxx].characters.length -- if it's zero, there are no characters connected. You should still check if it might have children, though, because it might be possible these still point to text.
(.. Thinking, while typing that last sentence: or maybe they don't .. logically, the 'parent' also points to each item 'in' it.)
Copy link to clipboard
Copied
Nope,
If you create a new document with two textframes, tag them "myTag", then delete one of the text frames, and run this:
var myTag = app.activeDocument.xmlElements[0];
$.write(myTag.characters.length, myTag.contents);
You still get the characters and contents out. The same goes for paragraph, texts.
I just cant find the difference between the tag with content on the page or the one without...
/Mikael
Copy link to clipboard
Copied
Hi,
Does anyone found a solution for this problem?
I have the same problem. I can't find out how to detect if the XML element is attached to a object on the page or not. It's a mistery ... Maybe future generations will remember this problem as the one problem that couldn't be solved ...
John
Copy link to clipboard
Copied
Here is an absurd way :
var doc = app.activeDocument;
var root=doc.xmlElements[0];
var n1 = root.xmlElements[0];
app.select(n1.parentStory.characters[0]); //Crashes Indesign if n1 is not placed in the document
But it doesn't help that much sorry. Looking further...
Loic
Copy link to clipboard
Copied
Maybe this way :
var doc = app.activeDocument;
var root=doc.xmlElements[0];
var n1 = root.xmlElements[0];
var n2= root.xmlElements[1];
try{
n1.insertionPoints[0].parent.texts[0].parentTextFrames[0].constructor;
alert("It's on the document !");
}
catch(e){
alert("No, it isn't !");
}
If a node is placed on the document you get access to the parent text frame. On the contrary, this call will fail if the node isn't placed.
Loic
Copy link to clipboard
Copied
I heard this works but haven't tried myself:
app.activeDocument.deleteUnusedTags()
Copy link to clipboard
Copied
Thanks Rob,
It do exactly what you expect, it deletes Unused Tags (From the tag list)
But Unused XML Elements, still there, and still bugging me.
/Mikael
Copy link to clipboard
Copied
If the (text) element is unplaced, its parentStory will be an XmlStory rather than a Story.
So try:
var elements = app.activeDocument.xmlElements[0].xmlElements.everyItem().getElements();
for (var i = elements.length - 1;i >= 0;i--){
if(elements.parentStory.constructor.name === "XmlStory"){
elements.remove();
}
}
This is untested. If you have tagged graphics frames it will need to be modified to not error on those.
Jeff
Copy link to clipboard
Copied
Does anyone solved this problem?
Copy link to clipboard
Copied
Hmmm, a little bit late for an answer, but this works for me. If someone would like to test it ...
var _xmlElement = app.activeDocument.xmlElements[0];
var _xmlPlaced = __isXMLElementPlaced(_xmlElement);
switch(_xmlPlaced) {
case true :
alert(_xmlElement.markupTag.name + " (or one of the children) placed");
break;
case false :
alert(_xmlElement.markupTag.name + " not placed");
break;
default :
alert("No valid XML Element.");
}
function __isXMLElementPlaced(_xmlElement) {
if(!_xmlElement || !_xmlElement.isValid || !(_xmlElement instanceof XMLElement)) {
return null;
}
var _xmlChildren;
var _numOfXMLChildren;
var _xmlChildPlaced;
var i;
if(_xmlElement.parentStory instanceof XmlStory && _xmlElement.xmlContent instanceof Text) {
_xmlChildren = _xmlElement.xmlElements.everyItem().getElements();
_numOfXMLChildren = _xmlChildren.length;
for(i=0; i<_numOfXMLChildren; i++) {
_xmlChildPlaced = __isXMLElementPlaced(_xmlChildren);
if(_xmlChildPlaced === true) {
return true;
}
}
return false;
} else {
return true;
}
} /* END function __isXMLElementPlaced */
Roland
Copy link to clipboard
Copied
Hi,
Try this:
var main = function() {
var doc = app.properties.activeDocument,
xes, xe;
if (!doc) return;
xes = doc.xmlElements[0].evaluateXPathExpression(".//*");
while ( xe = xes.pop() ) {
xe.texts[0].isValid && !xe.texts[0].parentTextFrames.length && xe.remove();
}
}
var u;
app.doScript("main();",u,u,UndoModes.ENTIRE_SCRIPT);
Copy link to clipboard
Copied
Hi Loic,
good idea with texts[0]. It works.
The reason why I ended up using a recursive function instead of xpath: some of the elements in my document are not placed, but have placed children.
Roland

Copy link to clipboard
Copied
I'm from Brazil, so excuse me for my imperfect English...
ctrl + alt + 1
Click on root when it open, select all archives, click on menu and
Than you can delet ROOT.
All the XML that is not actually being used will be deleted
Copy link to clipboard
Copied
Hi @Deleted User ,
thanks for your contribution!
FWIW:
This is an very old thread that started in 2010; you may have wondered why nobody did a suggestion like you did here.
My explanation:
This thread once belonged to a special forum called InDesign Scripting.
So only scripting solutions were discussed; ExtendScript (JavaScript), some AppleScript or VBScript in other threads.
Later, around October, November 2019, the InDesign Scripting forum was terminated due to a platform change and one by one over the years a lot of threads of that old InDesign Scripting forum were moved over to this InDesign User Forum here.
Regards,
Uwe Laubender
( Adobe Community Professional )

