5 Replies Latest reply on Apr 12, 2009 11:07 AM by Dave Saunders

    [JS CS3] Problem with iterating xml tags

    Tom Tomasko Level 1

      Hello,

       

      Below is a script that is supposed to find text in a document and then tag it with an xml tag. I have run into a problem, which if I solve in the way I know how, causes another problem.

       

      When I iterate in a positive direction--i++--the first instance of the text (in this example "abc") is correctly tagged. But the second instance the tag recedes by two characters, that is, tags the three characters prior to the "c." A third instance will recede two more characters, ad nauseam, if my Latin is correct.

       

      The solution is to iterate backwards, i.e., i--. But this causes another problem. If there is more than one story, then the xml structure reverses the order of the stories. The elements within a story are ordered correctly however.

       

      So why is this happening and how can I solve it?

       

      Thanks,

      Tom

       

      var myDoc = app.activeDocument;
      var findABC = theTextFinder(myDoc,"abc");
      xmlTagIt(myDoc,"abc",UIColors.RED,findABC);

       

      //*****functions*******
      function xmlTagIt(docRef, tagName,colorOfTag, arrToTag){
          var tagName, colorOfTag,  arrToTag;
          myDoc.xmlViewPreferences.showStructure = true;
          myDoc.xmlViewPreferences.showTaggedFrames =true;
          myDoc.xmlViewPreferences.showTagMarkers = true;
          myDoc.xmlViewPreferences.showTextSnippets =false;
          myDoc.xmlPreferences.defaultStoryTagColor = UIColors.WHITE;
          var rootElement = myDoc.xmlElements.item(0);
         
          if (myDoc.xmlTags.item(tagName) == null) {
              var tagRef = myDoc.xmlTags.add(tagName, colorOfTag);
        } else {//if tag already exists then stop the script. Avoid double tagging
             myDoc.xmlViewPreferences.showStructure = true;
             alert("You have already run this script.");
             exit();
         }//end else

       

          //for (var i = arrToTag.length-1; 0 <= i; i--){
          for (var i = 0; i <= arrToTag.length-1;  i++){
              var elementRef = rootElement.xmlElements.add (tagRef,arrToTag[i]);       
           }//end for i
      }//end function xmlTagIt
         
      function theTextFinder(docRef,textFindIt){//last argument is the string of text to find
          app.findTextPreferences = NothingEnum.NOTHING;
          app.changeTextPreferences = NothingEnum.NOTHING;
          app.findTextPreferences.findWhat = textFindIt;
          var arrTextFindIt = myDoc.findText();
          return arrTextFindIt;
      }//end theTextFinder

        • 1. Re: [JS CS3] Problem with iterating xml tags
          Dave Saunders Level 4

          The act of tagging inserts to "characters" into the text. That's what's happening when you iterate forwards.

           

          Since this is the only thing going on in your script you could convert the references on the fly. You'd have to keep track of whether or not you had changed stories to know how many characters the reference is off by.

           

          Alternatively (and perhaps more easily) you could iterate backwards and then reverse the order of the XML elements by moving them.

           

          Dave

          • 2. Re: [JS CS3] Problem with iterating xml tags
            Tom Tomasko Level 1

            Dave,

            Thanks for the reply.

            I'm not sure what you mean by "convert the references on the fly." You mean find a way to advance two characters forward and tag that? In the script I submitted here I am only searching for "abc," which of course I would not search or at all  in real life. The script uses grep to search for about twenty different typographical errors that typically appear and tags them all.

             

            Reiterating backwards seems, at first sight the way to go. But I haven't a clue as to how to reverse the order of the stories. I can get an array of stories, and array.reverse() them, but am not sure how to then make the script put this reversed order into the xml structure. Any hints?

             

            There, of course is bigger problem with the stories. If the document is written with one story created after another then the order of them is top to botom. But if say a text frame edited into the middle of all this, that story is still the last one in the xml structure. At least in one test, that was so. Maybe the way to solve this is to build an array of stories that have as one xml attribute the page it first appears on. Then order the array according to that attribute.

             

            Any advice you give will be appreciated.

             

            Thanks,

            Tom

            • 3. Re: [JS CS3] Problem with iterating xml tags
              Dave Saunders Level 4

              Tom,

               

              Assuming I'm understanding what you want to do, you're looking to:

               

              1. Tag text.

              2. Organize the xml structure to match the order of the stories in your document.

               

              The way to do the latter is to use the move method for xmlElements. This is not something I've done much so I'm not sure of the full implications, but as long as you move story tags around relative to each other, this will not affect the layout of the document, just the structure of the xml representation.

               

              Dave

              • 4. Re: [JS CS3] Problem with iterating xml tags
                Tom Tomasko Level 1

                Dave,

                Yes you are correct in understanding what I want to do. I'll have to experiment with  xmlElement.move(). At the moment I don't quite see how to use it because one has to state as an argument what the story elements are moving in relation to. That of course is the root element. But how does this order the stories? I'll have to play around and find out.

                Tom

                • 5. Re: [JS CS3] Problem with iterating xml tags
                  Dave Saunders Level 4

                  I assume that you have two story elements and you want to move one before the other. So, you'd write:

                   

                  myStoryElB.move(LocationOptions.before, myStoryElA);

                   

                  This would move story element B ahead of story element A in the structure panel, taking all its children elements with it.

                   

                  Dave