7 Replies Latest reply on Jan 6, 2013 6:54 AM by SLTyPete

    XML Rule + JS example: group elements under new parents

    SLTyPete

      Thanks again to everyone here for helping me get started! I'm now making real progress. In token of my appreciation, here's something that hopefully will eventually help others.

       

      I've worked out how to use the XML Rule facility (together w/ some JS management) to collect groups of XML elements and create new parent elements containing each group.

       

      The sample code here demonstrates several things in both JavaScript and InDesign Script, including:

      • Use of the XML Rules facility to quickly retrieve data from the XML structure
      • Use of the following-sibling XPath facility to obtain same-level XML elements
      • Creating XML tags, parent elements, and moving elements
      • Multi-dimensional JS array for managing XML elements

       

      By the way, here are a few more things that were not obvious to this noob (I'm sure they are documented; just took time to find them...)

      • In the InDesign script editor, you can bring up the Object Model Viewer by pressing F1
      • In the object model viewer, you must click below "Browser" and select the InDesign Object Model before doing a search
      • At the following link is a list of links to incredibly valuable documents and a huge collection of "Scripting Guide" sample scripts. http://www.adobe.com/products/indesign/indepth.displayTab2.html#Scriptingresources
      • Using try { xyzzy; } catch (myErr) { alert(myErr); }  ... is your friend

       

      Below is a description of what my sample code actually accomplishes. But first, here are some things I learned about the XML Rules facility. Probably obvious to someone who has used this before but hey, I'm new to this:

      1. You create a set of XML Rules and pass them to the "glue code." Each time the set of rules is run, a single (potentially complex) traversal is made through the XML Structure.
      2. The implication of #1 is that for any given element in the structure, the first rule that matches the element will process it. Thus, the sequence of rule definitions is always important. This both simplifies and sometimes makes more complex how one designs a set of rules.
      3. An example in my case:
        • I wanted to collect all elements at one level into "groups", with a particular (known) tag as the first element in each group.
        • It was pretty clear how to find the known tag; use an XPath like "/devices/name" if the tag is "name" underneath "/devices."
        • But how to collect the intervening tags? In normal XPath/XSLT syntax, this is a bit complicated. But in the XML Rule system, it's actually easy...
        • Since the first rule will always collect every "name" element, my second rule becomes simply "/devices/name/following-sibling::*" which means "collect all siblings after the 'name' element. Normally, that would include following name elements as well, but it does not do so here since the first rule collects those.
      4. Don't bother trying to rearrange the XML structure from within XML Rule processing. In certain limited situations it can work... but it is just as easy, and quite reliable, to collect the needed info during XML Rule processing, then make the structure changes as a later step.

       

       

      The MakeXMLGroups(myXPath,myParentTag,myHeadTag) function changes:

       

      Devices

         Name

         Type

         Desc

         Name

         Quantity

         Type

         Desc

         Name

         Desc

       

      To:

       

      Devices

        Device

            Name

            Type

            Desc

        Device

            Name

            Quantity

            Type

            Desc

        Device

             Name

            Desc

       

      In this case, the function call was MakeXMLGroups("/Devices","Device","Name").

       

      (NOTE: I'm on personal travel this week so may not get back to answer questions until next week...)

       

      Here are links to the necessary files:

      http://ds.org/files/adobe/MakeXMLGroups.jsx

      http://ds.org/files/adobe/grpXMLRulesExampleSetup.jsx

      http://ds.org/files/adobe/grpXMLRulesExampleData.xml

       

      Message was edited by: SLTyPete to insert file links

        • 1. Re: XML Rule + JS example: group elements under new parents
          John Hawkinson Level 5

          You can paste code using the Advanced Editor under >>.

           

          I'm sorry I haven't been around the forum much lately.

          If I had been, when you asked about XML Rules, I would have given you my "standard" reply:

           


           

          I would strongly discourage using the XML Rules logic in InDesign. It's very confusing to code, and while it has a template-based paradigm that might be familiar to those familiar with XSLT, it is pretty cumbersome to use. In my view, the sample code is also pretty problematic, because they don't show you how to parameterize it, and they depend a lot on code repitition.

           

          I'd encourage you to look at my example from Re: How to shift content with in cell in xml rules table (reply #20).

          • 2. Re: XML Rule + JS example: group elements under new parents
            SLTyPete Level 1

            Hi John,

             

            1) I like that the new model adds parameterization. It's cleaner than pulling in parameters from pre-set variables. However, the given example didn't actually make much use of it. The only non-constant parameter multiply-used in the example is the "table" variable. Seems like a lot of work for not a lot of gain, at least in this case?

             

            2) I am cautious that this new template/model condenses the paradigm sooo much, that it is no longer clear where XPath is involved vs straight constant tag names. Yes, Adobe's example is overly-expanded but that's common in code meant to be a demonstration.

             

            3) I also am cautious that the example intermingles direct node creation into the XPath search/processing chain. I've learned to be VERY careful with this. It only can work when the changes made do not interfere with the rule processing. In my model, I simply avoid it completely (by not making node-position or node-add/remove/move changes until after tree parsing is complete.) This will always be a safe model.

             

            Bottom line: while I very much appreciate the parameterization and lintability (is that a word? Sure makes sense to me )... I think I would still define each rule separately rather than bring them all together as an inline array in the rule processing call. To me it seems sooo condensed that the XPath meaning can become lost. (Would someone recognize that //para/section-head is actually an XPath statement that could (in another situation) be //para/* or //para/following-siblings::* ... while some of the other strings are exact-match tag names?)

             

            I realize this is all a matter of style... my preference: clarity for the future reader, particularly when the future reader is me a year later who forgot what all those parameters and embedded methods were all about ...

             

            Blessings,

            Pete

            • 3. Re: XML Rule + JS example: group elements under new parents
              John Hawkinson Level 5
              1) I like that the new model adds parameterization. It's cleaner than pulling in parameters from pre-set variables. However, the given example didn't actually make much use of it. The only non-constant parameter multiply-used in the example is the "table" variable. Seems like a lot of work for not a lot of gain, at least in this case?

              Well, to each his own. But to me, it's paving the way for future use.

               

              2) I am cautious that this new template/model condenses the paradigm sooo much, that it is no longer clear where XPath is involved vs straight constant tag names. Yes, Adobe's example is overly-expanded but that's common in code meant to be a demonstration.

              Well, I think you've gotta keep track of what the type of parameters are.

              I don't view there being a requirement to have the type of parameters obvious from looking inside them and not at their context.

               

              . (Would someone recognize that //para/section-head is actually an XPath statement that could (in another situation) be //para/* or //para/following-siblings::* ... while some of the other strings are exact-match tag names?)

              I'd sure think so -- what else would //foobar? But regardless, I don't think that sort of thng needs to be obvious at all.

               

              Anyhow, have fun!

              • 4. Re: XML Rule + JS example: group elements under new parents
                SLTyPete Level 1

                An important update: neither my method, nor any other method I've found, can work around what may be a bug in the current InDesign XML scripting system.

                 

                If you use a script to insert a new parent into the XML structure, you WILL destroy the existing paragraph styles of all content underneath the new parent. See the newer thread on this topic.

                 

                One reader mentioned that CS7 may be bringing significant XML improvements. That would be great. I wonder if there's a way to get on the prerelease team to test this... (hint )

                 

                Blessings,

                Pete

                • 5. Re: XML Rule + JS example: group elements under new parents
                  John Hawkinson Level 5

                  Hmm, I'll think about that problem and get back to you, but I'm not super-sanguine on it.

                  Of course, you could memorize the style structure and then go back and re-apply it after reparenting.

                   

                  There is very little overlap between the people who make prerelease program (and heck, regular plain program management) decisions and the membership of this forum. Actually, I think it's the null set. Now, people who are prerelease testers (probably) can't (or shouldn't?) tell you if they're prerelease testers, so who can say?

                   

                  I will say, in my considered opinion, I'm pretty puzzled what Loic is talking about in re "It seems that CS7 is going to review the XML engine." For two reasons. One, we know from at least public statements that the vast bulk of engineering work in InDesign CS7 is the migration to 64-bit compatibility and, on the Mac platform, the move away from the Carbon API to the Cocoa API. While one should not expect an utter dearth of new features, I would definitely not hold my breath. And secondly, well, it just doesn't seem too likely to me.

                   

                  As for prerelease testing, as above, nobody here is really involved in those decisions. Assuming you have filled out the form at http://adobe.com/go/beta, there's probably not too much more that you can do.

                  • 6. Re: XML Rule + JS example: group elements under new parents
                    John Hawkinson Level 5

                    Oh, right, I meant to add. The idea that CS7 might be going to have more XML features isn't really consistent with the idea of submitting feature requests via the wishform at this juncture. By all means do so, but product management tends to (and wants to) make feature decisions on a much longer timescale than this. If we figure CS7 is going to be released 3Q2013, then now would be a good time to be submitting feature requests for CS8 and CS9, not for CS7.

                     

                    I'm just trying to give you reasonable expectations...grains of salt all around, etc.

                    • 7. Re: XML Rule + JS example: group elements under new parents
                      SLTyPete Level 1

                      Makes sense, thanks!

                       

                      My pipe-dream hope at this point is that something might be incorporated as a bug fix...