Skip to main content
Mr Mossa
Participating Frequently
May 30, 2024
Question

Navigating XML structure

  • May 30, 2024
  • 1 reply
  • 242 views

Hi,

I am working on a script that looks for consecutive element names and adds a parent to those.

It shoudl be able to find the elements anywhere in the structure.

As long as the element has got the same parent,the same name and comes directly after the previous element, it is to be considered consecutive.

I have a somewhat working script, but it only works if the structure is flat, without sub elements to consider. This looks for <p> and <note> elements and puts them in a <info> element.
Note: The getAllElems() function collects all elements including all sub elements in the structure.

//Add the parent element Info to <p> and <note> elements founddirectly after eachother (It could be either one of them)
_addParentToConsecutiveElementsRegExVersion(/^(p|note)$/, "info");
function _addParentToConsecutiveElementsRegExVersion(elemNames, parentName){
    var allElems = getAllElems();
    var elemArr = [];
    for (var i = allElems.length - 1; i >= 0; i--){
        if (allElems[i].markupTag.name.match(elemNames)){
            var elemName = allElems[i].markupTag.name;
            elemArr.push(allElems[i]);
        }
        if (allElems[i].markupTag.name != String(elemName) && elemArr.length > 0 && allElems[i].parent.id == elemArr[elemArr.length-1].parent.id){
            var pE = elemArr[0].xmlElements.add(String(parentName));
            pE = pE.move(LocationOptions.BEFORE, elemArr[elemArr.length-1]);
            for (var j = elemArr.length - 1; j >= 0; j--){
                 elemArr[j] = elemArr[j].move(LocationOptions.AT_END, pE);
            }
            elemArr.length = 0;
        }
    }
}

 Example of the original structure:

<Root>
	<Story>
		<p>
		<cmd>
		<p>
		<note>
		<cmd>
		<cmd>
		<p>
		<p>
		<cmd>
		<step>
			<cmd>
			<p>
			<note>
		<step>
			<cmd>
			<p>
			<p>

 Example of the output I need:

<Root>
	<Story>
		<info>
			<p>
		<cmd>
		<info>
			<p>
			<note>
		<cmd>
		<cmd>
		<info>
			<p>
			<p>
		<cmd>
		<step>
			<cmd>
			<info>
				<p>
				<note>
		<step>
			<cmd>
			<info>
				<p>
				<p>

 

This topic has been closed for replies.

1 reply

Mr Mossa
Mr MossaAuthor
Participating Frequently
May 30, 2024

By the way, If you cannot come up with a good approach to this, I need something to easily get the previous element or the next element. It gets messy if elements have sub elements.....

leo.r
Community Expert
Community Expert
May 30, 2024

I think it would be easier for you to use existing tools to traverse the XML structure, such as XPath, instead of building your own routines (if I understand your question correctly).

 

EDIT: After reading your code more carefully, I realized that you go through actual InDesign elements (I thought you're just parsing XML code at first), so I'm less sure about my suggestion.