Loading ...
Sorry, an error occurred while loading the content.
 

Re: [XSL-FO] Including XML with tags in final document

Expand Messages
  • Eliot Kimber
    ... You can t just put the elements literally out into the FO--the FO processor will have no idea what to do with them. You have to convert the input elements
    Message 1 of 3 , May 16, 2005
      Adams, Kevin wrote:
      > I'm trying to create a document that contains the incoming XML exactly
      > as it appears, with tags, attributes and everything.
      > <fo:block>
      > <xsl:copy-of
      > select="/"/>
      > </fo:block>

      You can't just put the elements literally out into the FO--the FO
      processor will have no idea what to do with them. You have to convert
      the input elements to escaped text, which can do with something like this:

      <fo:block linefeed-treatment="preserve"
      white-space-treatment="preserve"
      white-space-collapse="false"
      >
      <xsl:apply-templates select="/" mode="copy-markup"/>
      </fo:block>

      <xsl:template match="*" mode="copy-markup"
      <xsl:text><</xsl:text>
      <xsl:value-of select="name(.)"/>
      <xsl:apply-templates select="@*" mode="copy-markup"/>
      <xsl:text>></xsl:text>
      <xsl:apply-templates mode="copy-markup"/>
      <xsl:text><</xsl:text>
      <xsl:value-of select="name(.)"/>
      </xsl:text>></xsl:text>
      </xsl:template>

      <xsl:template match="@*" mode="copy-markup">
      <xsl:text>
      </xsl:text><!-- newline and indention for each attribute -->
      <xsl:value-of select="concat(name(), '=')"/>
      <xsl:text>"</xsl:text>
      <xsl:value-of select="string(.)"/>
      <xsl:text>"</xsl:value-of><!-- NOTE: doesn't handle quotes in
      attribute values -->
      </xsl:template>

      <xsl:template match="text()" mode="copy-markup">
      <xsl:value-of select="."/>
      </xsl:template>


      This should get you pretty close. This is for XSLT 1.0 and doesn't take
      namespaces into account. A more complete, namespace-aware solution would
      be easier to do with XSTL 2.0. I also didn't account for processing
      instructions or comments, but you can probably figure that part out.

      Cheers,

      Eliot
      --
      W. Eliot Kimber
      Professional Services
      Innodata Isogen
      9390 Research Blvd, #410
      Austin, TX 78759
      (512) 372-8155

      ekimber@...
      www.innodata-isogen.com
    • G. Ken Holman
      ... So, you want the *text* of the markup, not the nodes of the markup. ... Yes, as nodes. ... Correct, because you ve passed as an element node, not as
      Message 2 of 3 , May 16, 2005
        At 2005-05-16 09:05 -0500, Adams, Kevin wrote:
        >I'm trying to create a document that contains the incoming XML exactly
        >as it appears, with tags, attributes and everything.

        So, you want the *text* of the markup, not the nodes of the markup.

        >I have a sample file like this:
        >
        ><document>
        > <tag1>Sample Text</tag1>
        ></document>
        >
        >My .xsl looks like this:
        > <fo:block>
        > <xsl:copy-of select="/"/>
        > </fo:block>
        >
        >Using the "<xsl:copy-of select="/"/>" does copy the entire structure
        >into the .fo file I create,

        Yes, as nodes.

        >but then FOP complains that the tags are not recognized.

        Correct, because you've passed <tag1> as an element node, not as text.

        It is your responsibility in the transformation to create the text you want
        from then nodes you have. Since XPath does *not* preserve the text that
        creates the nodes, then you have to mimic the text that might have created
        the nodes that you have.

        You could do something along the lines of the following (untested) to
        reconstitute candidate text that matches the nodes created according to the
        XPath model ... but it is not guaranteed to match your input syntax:

        <fo:block>
        <xsl:apply-templates mode="expose"/>
        </fo:block>


        <xsl:template mode="expose" match="*">
        <xsl:text/><<xsl:value-of select="name(.)"/>
        <xsl:for-each select="@*">
        <xsl:value-of select="concat(' ',name(.),'="',.,'"')"/>
        </xsl:for-each>
        <xsl:text>></xsl:text>
        <xsl:apply-templates mode="expose"/>
        <xsl:text/></<xsl:value-of select="name(.)"/>><xsl:text/>
        </xsl:template>

        The above does not consider edge cases such as an attribute containing a
        double quote.

        I hope this helps.

        . . . . . . . Ken

        --
        World-wide on-site corporate, govt. & user group XML/XSL training.
        G. Ken Holman mailto:gkholman@...
        Crane Softwrights Ltd. http://www.CraneSoftwrights.com/f/
        Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995)
        Male Breast Cancer Awareness http://www.CraneSoftwrights.com/f/bc
        Legal business disclaimers: http://www.CraneSoftwrights.com/legal
      Your message has been successfully submitted and would be delivered to recipients shortly.