3 Replies Latest reply on Aug 11, 2011 9:07 AM by John Hawkinson

    [XSL] Duplication?

    James Robinson Level 1

      I am not sure if this is a bug or just something I am doing wrong (probably the later).

      When I have an XML file I am importing, such as:

       

      <myArticle>

      <Content>

           <p>This is only a <b>test</b>.</p>

           <p>Some other paragraph of text.</p>

           <p>Yet another paragraph. <p>With another paragraph.</p></p>

      </Content>

      </myArticle>

       

      and I apply an XSL file:

       

      <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />

       

      <xsl:template match="/myArticle/Content//b">

           <xsl:element name="b"><xsl:apply-templates /></xsl:element>

      </xsl:template>

       

      <xsl:template match="/myArticle/Content//p">

           <xsl:element name="p"><xsl:apply-templates /></xsl:element>

      </xsl:template>

       

      <xsl:template match="/">

           <xsl:element name="body"><xsl:apply-templates select="/myArticle/Content//*" /></xsl:element>

      </xsl:template>

      </xsl:stylesheet>

       

      I get:

       

      <body>

           <p>This is only a <b>test</b>.</p>

           <b>test</b>

           <p>Some other paragraph of text.</p>

           <p>Yet another paragraph. <p>With another paragraph.</p></p>

           <p>With another paragraph.</p>

      </body>

       

      I expect to get:

       

      <body>

           <p>This is only a <b>test</b>.</p>

           <p>Some other paragraph of text.</p>

           <p>Yet another paragraph. <p>With another paragraph.</p></p>

      </body>

       

      Notice the duplication of sublevel items in the body tag? Any children of children under the Content tag are duplicated after the element they are within in under the new root element. Any suggestions?

        • 1. Re: [XSL] Duplication?
          John Hawkinson Level 5

          Style note: Please use >> Syntax Highlighting > XML in the web interface. It makes your code much more readable.

           

          <xsl:template match="/myArticle/Content//p">
               <xsl:element name="p"><xsl:apply-templates /></xsl:element>
          </xsl:template>
          

           

          This template's XPath expresion has //p so it will match all <p/> nodes beneath at any level.

          I think that is not what you want here, since it means it will match both the paragraph-within-paragraph and also its parent, so it prints them twice.

           

          I think your whole structure isn't quite right here ... I try to avoid XSLT as much as possible, but my recollection is you really want templates with constraints like match="p" rather than the sort of explicit positions you have.

           

          But it's also not normal to have nested <p> tags -- is that really the situation you have, or is it some other tag? I would say it is not a great way to structure your XML, and it may lead to, for instance, gross confusion on the part of the app that is reading the XML (such as InDesign).

           

          So consider doing it another way?

          1 person found this helpful
          • 2. Re: [XSL] Duplication?
            James Robinson Level 1

            John,

            Thanks for the tip. I didn't know there was syntax highlighting in the forums.

             

            Yes, sometimes there may be embedded tags of nearly any type. HTML is not an exact science (unfortunatly) so I have to prepare my transform for certain things that may be thrown at it.

             

            I believe I solved the issue. I changed

             

            <xsl:template match="/">
                 <xsl:element name="body"><xsl:apply-templates select="/myArticle/Content//*" /></xsl:element>
            </xsl:template>
            </xsl:stylesheet>
            

             

            to

             

            <xsl:template match="/">
                 <xsl:element name="body"><xsl:apply-templates select="/myArticle/Content" /></xsl:element>
            </xsl:template>
            </xsl:stylesheet>
            

             

            (got rid of the //* from the main template)

            and it is working correctly.

            • 3. Re: [XSL] Duplication?
              John Hawkinson Level 5

              Oh, yeah, that would do it! I picked on the wrong "//"!

              But I suspect you could still write it a lot simpler...