user5037156
user5037156

Reputation:

Html in an fop/xsl file

I am generating a PDF with FOP. The PDF contains a questionnaire section that has some simple HTML (i.e. <p> <strong> <em>) between the XML tags. My solution was to apply templates to these tags in the XSL file that would style everything between the <p> tags and so forth and so on. I have a basic template set up now, and I believe that I'm running into issues with how the XSL file finds the <p> tags within the XML. I think that since the HTML tags are located within another tag, my XSL doesn't work as expected. I wonder: how would you style these inner HTML tags using XSL templates?

The XML is generated as follows. You can see the HTML tags within the <QuestionText> tags.

<xml>
    <Report>
        <Stuff>
            <BasicInfo>
                <InfoItem>
                    <InfoName>ID</InfoName>
                    <InfoData>555</InfoData>
                </InfoItem>
                <InfoItem>
                    <InfoName>Name</InfoName>
                    <InfoData>Testing</InfoData>
                </InfoItem>
            </BasicInfo>

            <SubReports title="Employee Reports">
                <SubReport>
                    <Question>
                        <QuestionText>
                            <p>1. Are the pads secure?</p>
                        </QuestionText>
                        <AnswerText>Yes</AnswerText>
                    </Question>
                    <Question>
                        <QuestionText>
                            <p>
                                2. <strong>Are the pads in good shape?</strong>&nbsp;
                            </p>
                        </QuestionText>
                        <AnswerText>Yes</AnswerText>
                    </Question>
                </SubReport>
            </SubReports>
        </Stuff>
    </Report>
</xml>

Then I have an XSL template to style the XML

<xsl:template match="Stuff">
  <fo:block>
    <fo:block font-size="32pt" text-align="center" font-weight="bold">Report</fo:block>
  </fo:block>
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="SubReports">
  <xsl:for-each select="SubReport">
    <xsl:for-each select="Question">
      <fo:block xsl:use-attribute-sets="question"><xsl:apply-templates /></fo:block>
      <fo:block xsl:use-attribute-sets="answer"><xsl:value-of select="AnswerText" /></fo:block>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

<xsl:template match="SubReports/SubReport/Question/QuestionText">
  <fo:block><xsl:apply-templates /></fo:block>
</xsl:template>

<xsl:template match="SubReports/SubReport/Question/QuestionText/p">
  <fo:block padding-before="10pt"><xsl:apply-templates /></fo:block>
</xsl:template>

<xsl:template match="SubReports/SubReport/Question/QuestionText/strong">
  <fo:inline font-weight="bold"><xsl:apply-templates/></fo:inline>
</xsl:template>

<xsl:template match="SubReports/SubReport/Question/QuestionText/em">
  <fo:inline font-style="italic"><xsl:apply-templates/></fo:inline>
</xsl:template>

Are the match tags for the xsl:templates pointing to the right location on the HTML tags? If not, where should I point them? Thank you!

Upvotes: 1

Views: 1213

Answers (1)

Tim C
Tim C

Reputation: 70648

At the moment, your template matches have the full path to the element in match attribute

<xsl:template match="SubReports/SubReport/Question/QuestionText/strong">

But this won't match the strong element in the case where it is a child of the p element. Now, you could do this...

<xsl:template match="SubReports/SubReport/Question/QuestionText/p/strong">

But you don't actually need to specify the full path here though. Not unless you wanted to match a very specific element. This template match would also do the trick.

 <xsl:template match="strong">

So, you could replace your current templates with these instead

<xsl:template match="p">
  <fo:block padding-before="10pt"><xsl:apply-templates /></fo:block>
</xsl:template>

<xsl:template match="strong">
  <fo:inline font-weight="bold"><xsl:apply-templates/></fo:inline>
</xsl:template>

<xsl:template match="em">
  <fo:inline font-style="italic"><xsl:apply-templates/></fo:inline>
</xsl:template>

You are also using xsl:apply-templates so this work in the case of multiple nested HTML tags. For example <p><strong><em>Test</em></strong></p>

Upvotes: 3

Related Questions