1 Reply Latest reply on Aug 10, 2017 8:17 AM by S Hopkins

    XML looping over mixed content

    glennd87361366 Level 1

      This is something I have been wrestling with for a couple of hours now, although in different non working forms.

       

      I have a simple XML which I import through File > Import XML

       

      <?xml version="1.0" encoding="UTF-8"?>
      <doc>
        <page>
            <p id="1">
                hello <test />  alien world <br /> from space
            </p>
            <p id="2">
                hello <test /> another alien world <br /> from space
            </p>
        </page>
      </doc>
      

       

      For now my goal is rather simple namely iterate over all elements. This works until i'm at the point that I want to iterate over the (mixed) content within my p tags.

       

      // check version
      if (parseInt (app.version) > 4 && app.documents.length > 0){
      main();
      }
      
      
      function main() {
      // get active document
          var doc = app.activeDocument;
      
      
      // get xml that has been imported
          var xmlDocument = doc.xmlElements[0];
      
      
      // get page elements
      const page_elements = xmlDocument.evaluateXPathExpression('/doc/page')
      
      
      // iterate over page elements
      for(var x = 0; x < page_elements.length; x++) {
         // within each page element look for p elements
         const p_elements = page_elements[x].evaluateXPathExpression('./p');
      
         for(var y = 0; y < p_elements.length; y++) {
           
             var child_elements = p_elements[y].evaluateXPathExpression('./node()');
      
             for (var z = 0; z < child_elements.length; z++) {
               $.writeln(child_elements[z].markupTag.name);
               $.writeln(child_elements[z].contents);
             }
         }
      }
      }
      

       

      The problem is that doesn't seem to keep in mind the order of the child items.

       

      The output - according to the Extended Toolkit - is "p hello   alien world  from space test   br" while it should be "hello test alien world br from space".

       

      I'm basing myself on the documentation that is available here (Adobe InDesign CS4 (6.0) Object Model JS: Table of Contents, XML Suite ) including the usage of XmlElements or XmlItems but with no prevail :-(

       

      An alternative that I'm now thinking at is to read the xml file through javascript, creating a XML object from that string and go further from here.

        • 1. Re: XML looping over mixed content
          S Hopkins Adobe Community Professional

          Don't know exactly what you are wanting to accomplish here (reason for empty tags), but InDesign imports the XML correctly.

          Try it: Create a new document and import the XML. Open the structure pane (Mac:command+option+1). Your structure should look like this:

          doc 

              page

                 p

                 id = 1

                    test

                    br

             ...

          Now, create a text frame in the document. Drag the first p element from the structure pane into the text frame. You will have the text with a marker for the br element.

          Place the text cursor in the text and open the Story Editor pane. The text will read as follows:

             hello <test></test> alien world <br> </br> from space.

          Working with the XML structure as imported by InDesign you should be able to get what you want.

           

          Here is a simple script to demonstrate. It assumes page 1 has two text frames named "frame0" and "frame1"

          var frameRef;

          var frameName;

          var doc = app.documents[0];

          var pageRef = doc.pages[0];

          var rootElement = doc.xmlElements[0];

          var pageElements= rootElement.xmlElements;

          var pElement = pageElements[0];

          var cElements = pElement.xmlElements;

          for (var i = 0; i < cElements.length; i++) {

              frameName = ("frame" + i);

             frameRef = pageRef.pageItems.itemByName(frameName);

             cElements[i].placeXML(frameRef);

          }