Link to home
Start Free TrialLog in
Avatar of xtran-888
xtran-888

asked on

Using XSLT to convert XML to HTML

Hi,

Attached is the XML file: i'd like to use XSLT to group all info relating to a specific user eg. user1, and convert to HTML such as:
Name: 1
User 1 Code: 1111
Enable on partitions:
  Partition 1
  Partition 3
  Partition 5
Privileges:
 User 1 Supervisor
 User 1 Bypass
 User 1 Remote Access
____________________________
Name: 12
User 7 Code: 1212
Enable on partitions:
  Partition 3
Privileges:
 User 7 Bypass
____________________________
...
Customers.xml
Avatar of mccarl
mccarl
Flag of Australia image

Something like this should do what you need... (Note that it does make use of <xsl:for-each-group>, and therefore the result may depend on what XSLT processor you are using, this was tested with Saxon and works fine)
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/Users">
	<xsl:for-each-group select="User" group-by="Name">
	<xsl:sort select="Name" data-type="number"/>
		<h1>Name: <xsl:value-of select="current-grouping-key()"/></h1>
		<xsl:for-each select="current-group()/Phrase[contains(text(), 'Code')]/..">
			<h3><xsl:value-of select="Phrase"/>: <xsl:value-of select="Value"/></h3>
		</xsl:for-each>
		<h2>Enable on partitions</h2>
		<xsl:for-each select="current-group()/Phrase[matches(text(), 'User .* (Partition .*) Assignment')]/../Value[text()='Yes']/..">
			<p><xsl:value-of select="replace(Phrase, 'User .* (Partition .*) Assignment', '$1')"/></p>
		</xsl:for-each>
		<h2>Privileges</h2>
		<xsl:for-each select="current-group()/Phrase[not(matches(text(), 'User .* (Partition .*) Assignment'))]/../Value[text()='Yes']/..">
			<p><xsl:value-of select="Phrase"/></p>
		</xsl:for-each>
		<hr/>
	</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>

Open in new window

A few notes...
It's unfortunate that the XML doesn't have a richer structure that could be used to know which values are Partitions or Privileges, etc. The use of pattern matching to determine this is fraught with danger, but if that is all the XML can give you, then that is the best that can be done.
I put the <xsl:sort> element in there just to show you it can be done. If not needed it can be removed, or if the values of the <Name> elements are in fact normal alpha strings (not numbers as in your example) you can get rid of the data-type="number" attribute so that it sorts alpha strings properly.
Proper/nicer HTML formatting is left up to you! ;)
Avatar of xtran-888
xtran-888

ASKER

Hi,

Thanks for your help; but i could not run under VS2012 that
supports only XSLT 1.0. How can I get around this problem?

Regards,
XT
Hi,

Since i don't have XSLT2.0, i change my XML like:

<?xml version="1.0" encoding="utf-8"?>
<Users>
  <User>
    <Name>Panel User 1
    <Phrase>User 1 Code</Phrase>
    <Value>1111</Value>
    <Phrase>User 1 Supervisor</Phrase>
    <Value>Yes</Value>
    <Phrase>User 1 Bypass</Phrase>
    <Value>Yes</Value>
    <Phrase>User 1 Remote Access</Phrase>
    <Value>Yes</Value>
    <Phrase>User 1 Partition 1 Assignment</Phrase>
    <Value>Yes</Value>
    <Phrase>User 1 Partition 3 Assignment</Phrase>
    <Value>Yes</Value>
    <Phrase>User 1 Partition 5 Assignment</Phrase>
    <Value>Yes</Value>
    </Name>
  </User>
  <User>
    <Name>Panel User 5
    <Phrase>User 3 Code</Phrase>
    <Value>5555</Value>
    </Name>
  </User>
  <User>
    <Name>Panel User 4
    <Phrase>User 4 Code</Phrase>
    <Value>4444</Value>
    </Name>
  </User>
  <User>
    <Name>Panel User 2
    <Phrase>User 5 Code</Phrase>
    <Value>2222</Value>
    </Name>
  </User>
  <User>
    <Name>Panel User 6
    <Phrase>User 6 Code</Phrase>
    <Value>6666</Value>
    </Name>
  </User>
  <User>
    <Name>Panel User 12
    <Phrase>User 7 Code</Phrase>
    <Value>1212</Value>
    <Phrase>User 7 Bypass</Phrase>
    <Value>Yes</Value>
    <Phrase>User 7 Partition 3 Assignment</Phrase>
    <Value>Yes</Value>
    </Name>
  </User>
  <User>
    <Name>Panel User 10
    <Phrase>User 9 Code</Phrase>
    <Value>1010</Value>
    </Name>
  </User>
  <User>
    <Name>40
    <Phrase>Master Code</Phrase>
    <Value>1234</Value>
    </Name>
  </User>
</Users>

========================================
And my XSLT like:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="html" indent="yes"/>

    <xsl:template match="Users">
      <html>
        <body>

         
   
          <xsl:for-each select="User">
   
            <p>
              <xsl:value-of select="Name"/>
            </p>
 
            <xsl:for-each select="Phrase">
              <li>
                <ul>
                  <xsl:value-of select="Phrase"/>
                </ul>
 
              <span>
                <xsl:value-of select="Value"/>
              </span>
 
              </li>
            </xsl:for-each>
          </xsl:for-each>
           
 
        </body>
      </html>
    </xsl:template>
</xsl:stylesheet>


================================

And my output like:

Panel User 1








Panel User 5


Panel User 4


Panel User 2


Panel User 6


Panel User 12




Panel User 10


could you help since all phrases and values are missing? I don't understand.

Thanks,

Regards,
XT
ASKER CERTIFIED SOLUTION
Avatar of mccarl
mccarl
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for your help.