根据用户输入生成HTML(XML / XSLT)

时间:2016-04-02 00:07:11

标签: c# xml xslt

这个程序是如何工作的,它允许用户输入XML文件中存在的街道名称(XML中有更多的数据,但这里只有几个)。一旦用户输入街道名称,它将运行C#代码并使用XSLT创建布局,然后在HTML(Internet Explorer)中打开结果。

XML:

<allstops>
  <stop number="2504" name="Main &amp; Bainard EB">
    <location>
      <latitude>42.91033567</latitude>
      <longitude>-81.29671483</longitude>
    </location>
    <routes>28</routes>
  </stop>
<stop number="20" name="Adelaide &amp; Ada NB">
    <location>
      <latitude>42.9742886</latitude>
      <longitude>-81.2252341</longitude>
    </location>
    <routes>16</routes>
  </stop><stop number="2448" name="Homeview &amp; Golfview Cres S Leg NB">
    <location>
      <latitude>42.9459748</latitude>
      <longitude>-81.2503736</longitude>
    </location>
    <routes>26</routes>
  </stop>
<stop number="2448" name="Homeview &amp; 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中存在的任何街道,但它不会缩小搜索范围,只会输入我输入的街道名称。我想知道我是否缺少一行代码或者我编码不正确?

1 个答案:

答案 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">