繁体   English   中英

使用XPathNavigator.Select(xpath)找不到节点

[英]No nodes found with XPathNavigator.Select(xpath)

我正在创建C#控制台应用程序以查看站点号,名称,位置(纬度和经度)和路线号。 并在IE中打开xml文件,我已经创建了XSLT,并且XML文件遵循此Question Xpath和XSLT来将选定的数据显示为html 我添加了Xpath表达式以按名称查询stop,如下所示:

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:template match="/">
    <xsl:element name="html">
      <xsl:element name="body">
        <table style="width:720px" border="3">
          <tr>
            <td>Stop #</td>
            <td>Route #</td>
            <td>Name</td>
          </tr>
          <xsl:apply-templates select="//stop[@name=$theStreet]"/>
        </table>
      </xsl:element>
    </xsl:element>
  </xsl:template>
  <xsl:template match="stop">
    <tr>
      <td>
        <xsl:value-of select="@number"/>
      </td>
      <td>
        <xsl:value-of select="routes"/>
      </td>
      <td>
        <xsl:value-of select="@name"/>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

XML格式

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ltcstops.xslt"?>
<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="22" name="Adelaide &amp; Central Ave NB">
    <location>
      <latitude>42.9945666</latitude>
      <longitude>-81.2343441</longitude>
    </location>
    <routes>16</routes>
  </stop>
  <stop number="24" name="Adelaide &amp; Cheapside St NB">
    <location>
      <latitude>43.0064704</latitude>
      <longitude>-81.2401808</longitude>
    </location>
    <routes>16</routes>
  </stop>
</allstops>

错误:找不到预期的“应用模板”声明!

C#控制台应用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Xml;       // XmlDocument class
using System.Xml.XPath; // XPathNavigator class
using System.IO;        // Directory class

namespace BusStopApplication
{
    class Program
    {

        private const string XML_FILE = @"Documents\Visual Studio 2012\Projects\C#Project\BusStopApplication\BusStopApplication\ltcstops.xml"; 

        private const string XSLT_FILE_IN = @"Documents\Visual Studio 2012\Projects\C#Project\BusStopApplication\BusStopApplication\ltcstops.xslt";    

        private const string XSLT_FILE_OUT = "..\\..\\ltcstops_modified.xslt";
        static void Main(string[] args)
        {

           XmlDocument doc = new XmlDocument();
            doc.Load(XSLT_FILE_IN);

            // Obtain an XPathNavigator object
            XPathNavigator nav = doc.CreateNavigator();


            XmlNamespaceManager context = new XmlNamespaceManager(nav.NameTable);
            context.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");

            XPathExpression expr = nav.Compile("//xsl:variable[@name='theStreet']/@select");
            expr.SetContext(context);
            XPathNodeIterator nodes = nav.Select(expr);

         try
         {

           if (nodes.MoveNext())
            {
                // Get user's selection
                Console.Write("\nEnter street name: ");
                string street = Console.ReadLine();

                // Build a new 'select' attribute string for the apply-templates element
                string selectString = "//stop[@name='" + street.ToUpper() + "']";

                // Replace the select attribute 
                nodes.Current.SetValue(selectString);

                // Write new XSLT doc
                doc.Save(XSLT_FILE_OUT);

                // Display the transformed XML file in Internet Explorer

                // NOTE 4: 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() + "\\" + XML_FILE;
                proc.Start();
            }
            else
                Console.WriteLine("ERROR: Couldn't find the expected 'apply-templates' declaration!");
         }
         catch (System.Exception ex)
         {
             Console.WriteLine(ex.ToString());
         }

        }
    }
}

我添加了Xpath表达式以按名称查询stop,如下所示:XSLT

首先,XSLT样式表不是“ Xpath表达式”(尽管它包含XPath表达式)。

其次,您的XSLT样式表在第12行引用了一个未声明的变量$theStreet

-
似乎您正在尝试在运行时将参数传递给样式表。 我不知道如何在C#中执行此操作,但是您的样式表必须先声明此类参数,然后才能为其接收值。

看起来您想要做的是在XSLT中动态添加一个变量声明以创建一个新的XSLT,然后将其保存并用于显示XML? 建议您采用其他方法解决问题,而不是弄清楚为什么代码无法正常工作。

可以尝试向XSLT样式表中添加一个参数,然后使用XSLCompiledTransform在程序本身中执行转换,并以此传递参数,而不是尝试通过添加新语句然后在浏览器中打开XML来修改XSLT。 ,然后在浏览器中打开结果HTML。

首先,您的XSLT中应该有一个xsl:param (直接位于xsl:stylesheet下

 <xsl:param name="theStreet" />

然后,您将使用XSLCompiledTransform类实际执行到HTML的转换。 这是代码示例(在这种情况下,请使用硬编码的街道名称)。

using System.Diagnostics;
using System.Xml;
using System.Xml.Xsl;

namespace ConsoleApplication1
{
  class Program
  {
    private const string XML_FILE = @"Documents\ltcstops.xml";
    private const string XSLT_FILE_IN = @"Documents\ltcstops.xslt";
    private const string HTML_FILE_OUT = @"Documents\ltcstops.html";

    static void Main(string[] args)
    {
      // Create the XslCompiledTransform and load the stylesheet.
      XslCompiledTransform xslt = new XslCompiledTransform();
      xslt.Load(XSLT_FILE_IN);

      // Create the XsltArgumentList.
      XsltArgumentList xslArg = new XsltArgumentList();

      // Create a parameter which represents the current date and time.
      string streetName = "Adelaide & Ada NB";
      xslArg.AddParam("theStreet", "", streetName);

      // Transform the file. 
      using (XmlWriter w = XmlWriter.Create(HTML_FILE_OUT))
      {
        xslt.Transform(XML_FILE, xslArg, w);
      }

      Process proc = new System.Diagnostics.Process();
      proc.StartInfo.FileName = "iexplore";
      proc.StartInfo.Arguments = HTML_FILE_OUT;
      proc.Start();
    }
  }
}

然后打开的HTML应该只显示所选街道名称的详细信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM