Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transformation of XML into HTML: best practice?

I have XML like this:

<Artist name="Syd Mead" id="3412" ntrack="28" pop="8"/> 

Which I need to use in HTML markup:

<a href="#" data-name="Syd Mead" data-id="3412"
  data-ntrack="28" data-pop="8"
  class="pop-8"><span>Syd Mead</span></a>

What is the "right" way to do this for the widest array of browsers? Can this be done reliably with a XSLT transformation? Is it better to use a regex (unlikely) or do I have to parse out the xml, and for each <Artist> tag read each attribute and do document.createElement and setAttribute manually?

The <Artist> tags are in a parent node, there's many of them. Is there a best practice for this?

like image 882
artlung Avatar asked Jun 07 '12 05:06

artlung


3 Answers

This looks like a perfect candidate for XSLT - the XML is clean & well formed. If you're concerned about browser compatibility, why not do the transform on the server side?

This XSLT will transform your data - you can test it here:

Source data:

<Artists>
    <Artist name="Syd Mead" id="3412" ntrack="28" pop="8"/>
</Artists> 

XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:for-each select="Artists/Artist">
        <a href="#">
            <xsl:attribute name="data-id">      
                <xsl:value-of select="@id"/>
            </xsl:attribute>
            <xsl:attribute name="data-ntrack">      
                <xsl:value-of select="@ntrack"/>
            </xsl:attribute>
            <xsl:attribute name="data-pop">      
                <xsl:value-of select="@pop"/>
            </xsl:attribute>
            <xsl:attribute name="data-name">      
                <xsl:value-of select="@name"/>
            </xsl:attribute>
           <xsl:attribute name="class">    
                <xsl:value-of select="concat('pop-',@pop)"/>
           </xsl:attribute>

            <span><xsl:value-of select="@name"/></span>
        </a>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet> 

I haven't done this on the client side, so unfortunately I can't speak for browser compatibility.

like image 119
Simon MᶜKenzie Avatar answered Oct 19 '22 13:10

Simon MᶜKenzie


Here is a simple (no conditionals, no additional templates, no xsl:attribute, no xsl:for-each), short and complete transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="no"/>

 <xsl:template match="Artist">
     <a href="#" data-name="{@name}"
                 data-id="{@id}"
                 data-ntrack="{@ntrack}"
                 data-pop="{@pop}"
                 class="pop-{@pop}">
    <span><xsl:value-of select="@name"/></span>
  </a>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<Artist name="Syd Mead" id="3412" ntrack="28" pop="8"/>

the wanted, correct result is produced:

<a href="#" data-name="Syd Mead" data-id="3412" data-ntrack="28" data-pop="8" class="pop-8"><span>Syd Mead</span></a>

Explanation: Proper use of AVT (attribute Value Templates)

like image 5
Dimitre Novatchev Avatar answered Oct 19 '22 13:10

Dimitre Novatchev


Here's another XSLT stylesheet option that is simpler in my opinion:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"/>

    <xsl:template match="/*/Artist">
        <a href="#" class="pop-{@pop}"> 
            <xsl:apply-templates select="@*"/>
            <span><xsl:value-of select="@name"/></span>
        </a>        
    </xsl:template>

    <xsl:template match="@*">
        <xsl:attribute name="data-{name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

XML Input

<Artists>
    <Artist name="Syd Mead" id="3412" ntrack="28" pop="8"/> 
</Artists>

HTML Output

<a class="pop-8" href="#" data-name="Syd Mead" data-id="3412" data-ntrack="28" data-pop="8">
  <span>Syd Mead</span>
</a>
like image 2
Daniel Haley Avatar answered Oct 19 '22 13:10

Daniel Haley