0

How can I read an element/ tag like below - using xsl + xpath, I am trying to format the xml output to read the alignment tag from the style attribute, but I cannot figure it out... (last resort c#)

EDIT: To make my answer clear, I could be reading many html documents, I will most likely have a list of allowed tags that I need parsing so not everything will need parsing, as I am using xslt to transfortm teh document into xml I am writing my solution so far keeping only xsl + xpath in mind, however if I was to use c# and linq (to iterate over the document) - obviously that will set up all the styles then I will transform my document with other additions.

<h1 style="text-align: right;">Another chapter</h1>

My Xsl:

<xsl:template match="h1">
    <fo:block color="black" font-family="Arial, Verdana, sans-serif">
      <xsl:call-template name="set-alignment"/>
    </fo:block>
  </xsl:template>

<xsl:template name="set-alignment">
    <xsl:choose>
      <xsl:when test="@align='left'">
        <xsl:attribute name="text-align">start</xsl:attribute>
      </xsl:when>
      <xsl:when test="@align='center'">
        <xsl:attribute name="text-align">center</xsl:attribute>
      </xsl:when>
      <xsl:when test="@align='right'">
        <xsl:attribute name="text-align">end</xsl:attribute>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

Note, there is only one style defined below, but there could be many... (underline etc.)

Desired output:

<h1 text-align="start" text-decoration="underline" >Another chapter</h1>
2
  • 1
    With .NET 3.5 you could consider to move to XSLT 2.0 (you can choose between Saxon 9 saxon.sourceforge.net, XQSharp xqsharp.com, or AltovaXML Tools altova.com/altovaxml.html), then you could process the CSS style attribute with e.g. <xsl:for-each select="tokenize(@style, ';')"><xsl:attribute name="{normalize-space(substring-before(., ':'))}" select="normalize-space(substring-after(., ':'))"/></xsl:for-each>. Commented Mar 16, 2011 at 16:17
  • anything with budget constraints in mind... :) They look like they require a commercial license if ones application is not o/s Commented Mar 16, 2011 at 16:29

1 Answer 1

0

With the well known tokenization pattern, this stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="h1">
        <xsl:copy>
            <xsl:apply-templates select="@*[name()!='style']"/>
            <xsl:call-template name="tokenize-style"/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template name="tokenize-style">
        <xsl:param name="pString" select="string(@style)"/>
        <xsl:choose>
            <xsl:when test="not($pString)"/>
            <xsl:when test="contains($pString,';')">
                <xsl:call-template name="tokenize-style">
                    <xsl:with-param name="pString"
                         select="substring-before($pString,';')"/>
                </xsl:call-template>
                <xsl:call-template name="tokenize-style">
                    <xsl:with-param name="pString"
                         select="substring-after($pString,';')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:attribute name="{normalize-space(
                                         substring-before($pString,':')
                                      )}">
                    <xsl:value-of select="normalize-space(
                                             substring-after($pString,':')
                                          )"/>
                </xsl:attribute>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Output:

<h1 text-align="right">Another chapter</h1>
Sign up to request clarification or add additional context in comments.

2 Comments

genius! well known tokenization pattern in xsl... never found the reference to it anywhere...
@Haroon: I'm glad it was hepful. Some of the firsts references I could find stackoverflow.com/questions/1018974/… and stackoverflow.com/questions/136500/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.