Использование Xpath над возвращаемым значением метода расширения XSLT - PullRequest
2 голосов
/ 10 июля 2011

У меня есть xml, возвращаемый методом расширения. Могут ли некоторые помочь мне использовать <xsl:for-each> в этом xml.

public class CustomObj
{
    //function that gets called from XSLT
    public XPathNodeIterator GetResultTable()
    {
        DataTable table = new DataTable("Table1");

        table.Columns.Add("SourceCity");
        table.Columns.Add("DestinationCity");
        table.Columns.Add("Fare");

        table.Rows.Add(new object[] { "New York", "Las Vegas", "100" });
        table.Rows.Add(new object[] { "New York", "London", "200" });
        table.Rows.Add(new object[] { "New York", "New Delhi", "250" });

        StringWriter writer = new StringWriter();
        table.WriteXml(writer);

        XmlDocument doc = new XmlDocument();
        XmlElement root = doc.CreateElement("Root");
        root.InnerXml = writer.ToString();
        doc.AppendChild(root);

        return doc.CreateNavigator().Select("root");
    }
}

Я хочу перебрать этот xml. Кто-нибудь, пожалуйста, помогите. Я новичок в XSLT и был бы признателен, если бы вы могли привести пример с самим данным xml.

1 Ответ

2 голосов
/ 11 июля 2011

Следует отметить две вещи :

  1. Гораздо более естественно применить преобразование к результату вызова метода GetResultTable(), чем получить его результат с помощью функции расширения.

  2. Как написано, метод GetResultTable() вообще не возвращает ни одного узла: в операторе

-

   return doc.CreateNavigator().Select("root");

метод Select() ничего не выбирает, так как в doc нет элемента root. Элемент с именем Root не выбран, так как XML и XPath чувствительны к регистру.

Другое наблюдение состоит в том, что совсем не обязательно использовать xsl:for-each в XSLT-преобразовании - в большинстве случаев это считается плохой практикой.

Сказав это, вот полный код того, что задает этот вопрос :

namespace TestXml
{
    using System;
    using System.Data;
    using System.IO;
    using System.Xml;
    using System.Xml.XPath;
    using System.Xml.Xsl;

    class Program
    {
        static void Main(string[] args)
        {
            CustomObj co = new CustomObj();
            XPathNodeIterator xpni = co.GetResultTable();

            XslCompiledTransform xslt = new XslCompiledTransform(true);
            xslt.Load(@"..\..\My.xslt");

            XsltArgumentList xargs = new XsltArgumentList();
            xargs.AddExtensionObject("my:extension", co);

            XmlDocument fakeDoc = new XmlDocument();
            fakeDoc.LoadXml("<t/>");

            StringWriter sw = new StringWriter();

            xslt.Transform(fakeDoc.CreateNavigator(), xargs, sw);

            string result = sw.ToString();

            Console.Write(result);
        }
    }

    public class CustomObj
    {    //function that gets called from XSLT    
        public XPathNodeIterator GetResultTable()    
        {        
            DataTable table = new DataTable("Table1");        
            table.Columns.Add("SourceCity");        
            table.Columns.Add("DestinationCity");        
            table.Columns.Add("Fare");        
            table.Rows.Add(new object[] { "New York", "Las Vegas", "100" });        
            table.Rows.Add(new object[] { "New York", "London", "200" });        
            table.Rows.Add(new object[] { "New York", "New Delhi", "250" });        
            StringWriter writer = new StringWriter();        
            table.WriteXml(writer);        
            XmlDocument doc = new XmlDocument();        
            XmlElement root = doc.CreateElement("Root");        
            root.InnerXml = writer.ToString();        
            doc.AppendChild(root);        
            return doc.CreateNavigator().Select("Root");    
        }
    }
}

и файл My.xslt:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:extension"
 exclude-result-prefixes="my">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/">
    <html>
      <table border="1">
        <tr>
          <td>Source</td>
          <td>Destination</td>
          <td>Fare</td>
        </tr>
        <xsl:apply-templates select="my:GetResultTable()/*/Table1"/>
      </table>
    </html>
  </xsl:template>

  <xsl:template match="Table1">
    <tr>
      <xsl:apply-templates/>
    </tr>
  </xsl:template>

  <xsl:template match="Table1/*">
    <td>
      <xsl:apply-templates/>
    </td>
  </xsl:template>
</xsl:stylesheet>

Когда приложение выполняется, выдается нужный, правильный результат :

<html>
  <table border="1">
    <tr>
      <td>Source</td>
      <td>Destination</td>
      <td>Fare</td>
    </tr>
    <tr>
    <td>New York</td>
    <td>Las Vegas</td>
    <td>100</td>
  </tr>
    <tr>
    <td>New York</td>
    <td>London</td>
    <td>200</td>
  </tr>
    <tr>
    <td>New York</td>
    <td>New Delhi</td>
    <td>250</td>
  </tr>
  </table>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...