<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE MSMAG SYSTEM "MsMag.dtd">
<?xml-stylesheet type="text/xsl" href="MsMag.xsl"?>
<MSMAG name="&MIND;" publisher="&MFI;" description="&MIND_D;">
<EDITORIAL volume="4" number="3" month="March" />
<COVER
title="Windows 2000"
subtitle="What Every Web Developer Needs to Know">
</COVER>
<ARTICLES>
<FEATURE author="D. Esposito">
Windows 2000 for Web Developers</FEATURE>
<FEATURE author="B. Shankle">
Find Recombinant Success with Windows DNA</FEATURE >
<FEATURE author="M. Tabini">
Using Stored Procedures in SQL Server</FEATURE>
<FEATURE author="C. Nolan">
Put Advanced SQL Server Features to Work</FEATURE>
<COLUMN name="Flux" author="D. Boling">
Pentium III</COLUMN>
<COLUMN name="New Stuff" author="T. Carey">
</COLUMN>
<COLUMN name="Geektogeek" author="R. Hess">
</COLUMN>
<COLUMN name="Beyond the Browser" author="K. Spencer">
Visual InterDev 6.0 Form Manager</COLUMN>
<COLUMN name="FAQ" author="K. Kotipalli">
Namespace Extension AppWizard</COLUMN>
<COLUMN name="Extreme C++" author="S. Zimmerman">
Scalability, State and MTS</COLUMN>
</ARTICLES>
</MSMAG>
Figure 5 MsMag.dtd
<!-- Document Type Definition for a Magazine Language -->
<!ENTITY MSJ "Microsoft Systems Journal">
<!ENTITY MIND "Microsoft Internet Developer">
<!ENTITY MIND_D "The Microsoft Magazine for Web Developers">
<!ENTITY MFI "Miller Freeman">
<!ENTITY % Binary "yes | no">
<!ELEMENT MSMAG (EDITORIAL, COVER*, ARTICLES, COMMENTS?)>
<!ATTLIST MSMAG name CDATA #REQUIRED
publisher CDATA #REQUIRED
description CDATA #IMPLIED>
<!ELEMENT EDITORIAL (#PCDATA)>
<!ATTLIST EDITORIAL volume CDATA #IMPLIED
number CDATA #IMPLIED
month CDATA #IMPLIED
year CDATA "1999"
published (%Binary;) #IMPLIED>
<!ELEMENT COVER (#PCDATA)>
<!ATTLIST COVER title CDATA #REQUIRED
subtitle CDATA #REQUIRED>
<!ELEMENT ARTICLES (FEATURE+, COLUMN+)>
<!ELEMENT FEATURE (#PCDATA)>
<!ATTLIST FEATURE author CDATA #REQUIRED>
<!ELEMENT COLUMN (#PCDATA)>
<!ATTLIST COLUMN name CDATA #REQUIRED
author CDATA #REQUIRED>
<!ELEMENT COMMENTS (#PCDATA)>
Figure 6
Common XSL Keywords
Keyword |
Description |
<xsl:template match=tag> |
Defines the HTML code for the given XML tag. |
<xsl:value-of select=name> |
Returns the value of the specified tag attribute or the text associated with the node. |
<xsl:for-each select=name> ... |
Repeats what follows for each element that matches the specified tag name. |
</xsl:for-each> <xsl:apply-templates match=name> |
Applies all the possible templates to the elements that match the description. |
<xsl:eval>FuncName()</xsl:eval> |
Evaluates a piece of script code (VBScript or JScript). FuncName is the name of the function to execute. What the function returns replaces the command. The function can access the XML object model using this as the entry point to the XML root node. |
<xsl:element name="Name"> |
Defines an HTML element dynamically. Within the body you can add as many attributes as needed. |
<xsl:attribute name=name> Value</xsl:attribute> |
Defines an attribute for an element. The name field is the name of the attribute while the content of the tag is the value assigned to the attribute. |
Figure 7 MsMag.xsl
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"
xmlns:html="http://www.w3.org/TR/REC-html40"
result-ns=""
language="JScript">
<xsl:template match="/">
<HTML>
<HEAD>
<LINK REL="stylesheet" TYPE="text/css" HREF="msmag.css"/>
<TITLE><xsl:value-of select="MSMAG/@name"/>, <xsl:value-of select="MSMAG/EDITORIAL/@month"/>
<xsl:value-of select="MSMAG/EDITORIAL/@year"/> </TITLE>
</HEAD>
<BODY>
<TABLE width="100%">
<TR>
<TD class="EditVolume">Volume <xsl:value-of select="MSMAG/EDITORIAL/@volume"/> </TD>
<TD class="EditVolume">Number <xsl:value-of select="MSMAG/EDITORIAL/@number"/> </TD>
<TD class="EditIssue">
<xsl:value-of select="MSMAG/EDITORIAL/@month"/> <xsl:value-of select="MSMAG/EDITORIAL/@year"/>
</TD>
</TR>
</TABLE>
<HR />
<TABLE width="100%">
<TD class="Desc"> <xsl:value-of select="MSMAG/@description"/> </TD>
<TD class="Publ"> <xsl:value-of select="MSMAG/@publisher"/> </TD>
</TABLE>
<HR />
<TABLE width="100%">
<TR><TD class="Magz"> <xsl:value-of select="MSMAG/@name"/> </TD></TR>
<TR><TD class="IssueTitle"><xsl:eval>GetTitle()</xsl:eval> </TD></TR>
<TR><TD class="IssueSubTitle"> <xsl:eval>GetSubTitle()</xsl:eval> </TD></TR>
</TABLE>
<TABLE width="100%">
<TR>
<TD valign="top">
<TABLE bgcolor="lightyellow" border="1" width="100%">
<TR><TH class="ColTitle">Features</TH></TR>
<TD class="StdText">
<xsl:for-each select="MSMAG/ARTICLES">
<xsl:apply-templates select="FEATURE"/>
</xsl:for-each>
</TD>
</TABLE>
</TD>
<TD valign="top">
<TABLE bgcolor="lightgrey" border="1" width="100%">
<TR><TH class="ColTitle">Columns</TH></TR>
<TD class="StdText">
<xsl:for-each select="MSMAG/ARTICLES">
<xsl:apply-templates select="COLUMN"/>
</xsl:for-each>
</TD>
</TABLE>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:script language="JScript">
<![CDATA[
function GetTitle() {
list = this.selectNodes("MSMAG/COVER");
if (list.length == 0)
return "No title provided";
else
return list.item(0).attributes.getNamedItem("title").text;
}
function GetSubTitle() {
list = this.selectNodes("MSMAG/COVER");
if (list.length == 0)
return "No subtitle provided";
else
return list.item(0).attributes.getNamedItem("subtitle").text;
}
]]>
</xsl:script>
<xsl:template match="COLUMN">
<B><xsl:value-of select="@name"/>-</B> <xsl:value-of select="@author"/>,
<I><xsl:value-of /></I> <HR />
</xsl:template>
<xsl:template match="FEATURE">
<xsl:value-of select="@author"/>, <I><xsl:value-of /></I> <HR />
</xsl:template>
</xsl:stylesheet>
Figure 10 Detecting the Browser
<%
uAgent = Request.ServerVariables("HTTP_USER_AGENT")
if Instr(uAgent, "MSIE 5.0") <= 0 then
Set xml = Server.CreateObject("Microsoft.XMLDOM")
Set xsl = Server.CreateObject("Microsoft.XMLDOM")
' fully-qualified name for the XML and XSL files
path = Request.ServerVariables("PATH_TRANSLATED")
fileXML = Replace(path, ".asp", ".xml", 1)
fileXSL = Left(path, InstrRev(path, "\")) + "MsMag.xsl"
' load the documents
xml.load(fileXML)
xsl.load(fileXSL)
' return the related HTML code
Response.Write xml.transformNode(xsl.documentElement)
Response.End
end if
%>
Figure 11 XML for Other Browsers
<%
uAgent = Request.ServerVariables("HTTP_USER_AGENT")
if Instr(uAgent, "MSIE 5.0") <= 0 then
Set xml = Server.CreateObject("Microsoft.XMLDOM")
Set xsl = Server.CreateObject("Microsoft.XMLDOM")
' get the fully-qualified name for the XML and XSL files
path = Request.ServerVariables("PATH_TRANSLATED")
fileXML = Replace(path, ".asp", ".xml", 1)
fileXSL = Left(path, InstrRev(path, "\")) + "MsMag.xsl"
' read the ASP file into a variable
Set fso = Server.CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(path, 1, 0)
strXML = f.ReadAll()
f.Close
' strip off the chars until the final %
strEndAsP = Chr(37) & ">"
x = Instr(strXML, strEndASP)
strXML = Right(strXML, Len(strXML)-x-(Len(strEndASP)+1))
' creates a XML file on the fly and assigns it the XML body
Set f = fso.CreateTextFile(fileXML)
f.Write strXML
f.Close
' load the documents
xml.load(fileXML)
xsl.load(fileXSL)
' return the related HTML code and delete the temp XML file
Response.Write xml.transformNode(xsl.documentElement)
fso.DeleteFile fileXML
Response.End
end if
%>
Figure 12 A Typical XML Server Page
<%
uAgent = Request.ServerVariables("HTTP_USER_AGENT")
if Instr(uAgent, "MSIE 5.0") <= 0 then
Set xml = Server.CreateObject("Microsoft.XMLDOM")
Set xsl = Server.CreateObject("Microsoft.XMLDOM")
' get the fully-qualified name for the XML and XSL files
path = Request.ServerVariables("PATH_TRANSLATED")
fileXML = Replace(path, ".asp", ".xml", 1)
fileXSL = Left(path, InstrRev(path, "\")) + "MsMag.xsl"
' read the ASP file into a variable
Set fso = Server.CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(path, 1, 0)
strXML = f.ReadAll()
f.Close
' strip off the chars until the final %
strEndAsP = Chr(37) & ">"
x = Instr(strXML, strEndASP)
strXML = Right(strXML, Len(strXML)-x-(Len(strEndASP)+1))
' creates a XML file on the fly and assigns it the XML body
Set f = fso.CreateTextFile(fileXML)
f.Write strXML
f.Close
' load the documents
xml.load(fileXML)
xsl.load(fileXSL)
' return the related HTML code
Response.Write xml.transformNode(xsl.documentElement)
fso.DeleteFile fileXML
Response.End
end if
%>
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="MsMag.xsl"?>
<!DOCTYPE MSMAG SYSTEM "MsMag.dtd">
<MSMAG name="&MIND;" publisher="&MFI;" description="&MIND_D;">
<EDITORIAL volume="4" number="3" month="March" />
<COVER
title="Windows 2000"
subtitle="What Every Web Developer Needs to Know">
</COVER>
<ARTICLES>
<FEATURE author="D. Esposito">
Windows 2000 for Web Developers</FEATURE>
<FEATURE author="B. Shankle">
Find Recombinant Success with Windows DNA</FEATURE >
<FEATURE author="M. Tabini">
Using Stored Procedures in SQL Server</FEATURE>
<FEATURE author="C. Nolan">
Put Advanced SQL Server Features to Work</FEATURE>
<COLUMN name="Flux" author="D. Boling">
Pentium III</COLUMN>
<COLUMN name="New Stuff" author="T. Carey">
</COLUMN>
<COLUMN name="Geektogeek" author="R. Hess">
</COLUMN>
<COLUMN name="Beyond the Browser" author="K. Spencer">
Visual InterDev 6.0 Form Manager</COLUMN>
<COLUMN name="FAQ" author="K. Kotipalli">
Namespace Extension AppWizard</COLUMN>
<COLUMN name="Extreme C++" author="S. Zimmerman">
Scalability, State and MTS</COLUMN>
</ARTICLES>
</MSMAG>
Figure 13 XML to HTML Offline Converter
// CreateHTML.js
// XML to HTML converter
//
// Usage: CreateHTML xml xsl html
// --------------------------------------------------------
var xml, xsl;
var fileXML, fileXSL, fileHTM;
var fso, f;
fileXML = WScript.Arguments(0);
fileXSL = WScript.Arguments(1);
fileHTM = WScript.Arguments(2);
xml = new ActiveXObject("Microsoft.XMLDOM");
xsl = new ActiveXObject("Microsoft.XMLDOM");
xml.load(fileXML);
xsl.load(fileXSL);
fso = new ActiveXObject("Scripting.FileSystemObject");
f = fso.CreateTextFile(fileHTM);
f.Write(xml.transformNode(xsl.documentElement));
f.Close();