这个程序是如何工作的,它允许用户输入XML文件中存在的街道名称(XML中有更多的数据,但这里只有几个)。一旦用户输入街道名称,它将运行C#代码并使用XSLT创建布局,然后在HTML(Internet Explorer)中打开结果。
XML:
<allstops>
<stop number="2504" name="Main & Bainard EB">
<location>
<latitude>42.91033567</latitude>
<longitude>-81.29671483</longitude>
</location>
<routes>28</routes>
</stop>
<stop number="20" name="Adelaide & Ada NB">
<location>
<latitude>42.9742886</latitude>
<longitude>-81.2252341</longitude>
</location>
<routes>16</routes>
</stop><stop number="2448" name="Homeview & Golfview Cres S Leg NB">
<location>
<latitude>42.9459748</latitude>
<longitude>-81.2503736</longitude>
</location>
<routes>26</routes>
</stop>
<stop number="2448" name="Homeview & Golfview Cres S Leg NB">
<location>
<latitude>42.9459748</latitude>
<longitude>-81.2503736</longitude>
</location>
<routes>26</routes>
</stop>
</allstops>
XSLT:
<?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:param name="name" />
<xsl:template match="/">
<html>
<body>
<h1>
<font face="Verdana">
LTC Stops on <xsl:value-of select="$name"/>
</font>
</h1>
<h2>
<font face="Verdana">
<xsl:value-of select="count(//stop)"/> stops found
</font>
</h2>
<table style="width:720px" border="3">
<tr>
<th>
<font face="Verdana" size="4">Stop #</font>
</th>
<th>
<font face="Verdana" size="4">Stop Name</font>
</th>
<th>
<font face="Verdana" size="4">Latitude</font>
</th>
<th>
<font face="Verdana" size="4">Longitude</font>
</th>
<th>
<font face="Verdana" size="4">Routes</font>
</th>
</tr>
<xsl:apply-templates select ="//stop">
<xsl:sort select="@number" data-type="number" order="ascending" />
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="stop">
<xsl:element name="tr">
<xsl:element name="td">
<xsl:value-of select="@number"/>
</xsl:element>
<xsl:element name="td">
<xsl:value-of select="@name"/>
</xsl:element>
<xsl:element name="td">
<xsl:value-of select=".//latitude"/>
</xsl:element>
<xsl:element name="td">
<xsl:value-of select=".//longitude"/>
</xsl:element>
<xsl:element name="td">
<xsl:value-of select=".//routes"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
C#:
using System;
using System.Xml.Xsl; // Xslt types
using System.IO; // Directory class
namespace GetLTCStops
{
class Program
{
/*
* The following constants assume all the files are located
* in the solution folder which is three folders up from the
* program's runtime folder.
*/
private const string XML_FILE = @"..\..\..\Ltcstops.xml";
private const string XSLT_FILE = @"..\..\..\Ltcstops.xslt";
private const string XSLT_FILE_TWO = @"..\..\..\Ltcstops1.xslt";
private const string HTML_FILE = @"..\..\..\Ltcstops.html";
static void Main(string[] args)
{
// Display a title
Console.WriteLine("London Transit Comission Bus Stop Report");
Console.WriteLine("----------------------------------------");
Console.WriteLine("\nProvide a street name or partial street name exactly as it appears in the XML file.");
string streetName;
do
{
// Get the name of a character from the usuer
Console.Write("\nEnter Street: ");
streetName = Console.ReadLine().ToUpper().Trim();
if (streetName.Length == 0)
{
// Create a new XslTransform object and load the style sheet
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XSLT_FILE_TWO);
// Set-up an XsltArgumentList object to pass to the
// XSLT file's 'character' parameter
XsltArgumentList xsltArgList = new XsltArgumentList();
// Execute the transformation
FileStream outFile = File.Create(HTML_FILE);
xslt.Transform(XML_FILE, xsltArgList, outFile);
outFile.Close();
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "iexplore";
proc.StartInfo.Arguments = Directory.GetCurrentDirectory().ToString() + "\\" + HTML_FILE;
proc.Start();
}
}
while (streetName.Length == 0);
try
{
// Create a new XslTransform object and load the style sheet
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XSLT_FILE);
// Set-up an XsltArgumentList object to pass to the
// XSLT file's 'name' parameter
XsltArgumentList xsltArgList = new XsltArgumentList();
xsltArgList.AddParam("name", "", streetName);
// Execute the transformation
FileStream outFile = File.Create(HTML_FILE);
xslt.Transform(XML_FILE, xsltArgList, outFile);
outFile.Close();
// Display the transformed XML file in Internet Explorer
// The rutime folder used by the Internet Explorer (IE) program is
// different from the one used by our C# program. So we're going to give
// IE the absolute path to the XML file by using the GetCurrentDirectory() method.
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "iexplore";
proc.StartInfo.Arguments = Directory.GetCurrentDirectory().ToString() + "\\" + HTML_FILE;
proc.Start();
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
} // end Main method
} // end class
} // end namespace
我遇到的问题是,我可以进入XML中存在的任何街道,但它不会缩小搜索范围,只会输入我输入的街道名称。我想知道我是否缺少一行代码或者我编码不正确?
答案 0 :(得分:0)
您需要使用参数来过滤节点,因此请使用例如
<xsl:param name="name" />
<xsl:key name="filter" match="stop" use="@name"/>
<xsl:variable name="filtered-stops" select="key('filter', $name)"/>
然后使用<xsl:value-of select="count($filtered-stops)"/>
代替<xsl:value-of select="count(//stop)"/>
和<xsl:apply-templates select ="$filtered-stops">
代替<xsl:apply-templates select ="//stop">
。