listBox1.Items.Add("Total Cost = "
+ nav.Evaluate("sum(/bookstore/book[@genre='novel']/price)"));
}
При этом вывод изменится следующим образом:
Пространство имен System.Xml.Xsl содержит классы XSL, применяемые .NET. XslTransform может использоваться с любым хранилищем, которое реализует интерфейс IXPathNavigable. В настоящее время на платформе .NET это: XmlDocument, XmlDataDocument и XPathDocument. Так же как и в случае XPath, воспользуйтесь тем хранилищем, которое подходит лучшим образом. Если планируется создание заказного хранилища, такого как файловая система, и желательно иметь возможность выполнять преобразования, не забудьте реализовать в классе интерфейс IXPathNavigable.
XslTransform основывается на потоковой модели запросов. В связи с этим можно соединить несколько преобразования вместе. Можно даже применять, если нужно, между преобразованиями заказной объект чтения. Это предоставляет большую гибкость при проектировании.
В первом примере, который мы рассмотрим, берется документ books.xml и преобразуется в простой документ HTML для вывода. (Этот код можно найти в папке XPathXSLSample3.) Необходимо будет добавить следующие операторы using:
using System.IO;
using System.Xml.Xsl;
using System.Xml.XPath;
Вот код, выполняющий преобразование:
private void button1_Click(object sender System.EventArgs e) {
//создать новый XPathDocument
XPathDocument doc=new XPathDocument("..\\..\\..\\booksxpath.XML");
// создать новый XslTransForm
XslTransform transForm=new XslTransform();
transForm.Load("..\\..\\..\\books.xsl");
// этот FileStream будет нашим выводом
FileStream fs=new FileStream("..\\..\\..\\booklist.html", FileMode.Create);
// Создать Navigator
XPathNavigator nav=((IXPathNavigable)doc).CreateNavigator();
// Выполнить преобразование. Файл вывода создается здесь.
transForm.Transform(nav, null, fs);
}
Сделать это преобразование проще почти невозможно. Сначала создается объект на основе XPathDocument и объект на основе XslTransform. Затем файл bookspath.xml загружается в doc, a books.xsl в transForm. В этом примере для записи нового документа HTML на диск создается объект FileStream.
Если бы это было приложение ASP.NET, мы использовали бы объект TextWriter и передавали бы его в объект HttpResponse. Если бы мы преобразовывали в другой документ XML, то применялся бы объект на основе XmlWriter. После того как объекты XPathDocument и XslTransform будут готовы, мы создаем XPathNavigator на doc и передаем nav и этот stream в метод Transform объекта transForm. XslTransform имеет несколько перегружаемых версий, получающих комбинации навигаторов, XsltArgumentList (подробнее об этом позже) и потоков ввода/вывода. Параметром навигатора может быть XPathNavigator или любой объект, реализующий интерфейс IXPathNavigable. Потоки ввода/вывода могут быть TextWriter, Stream или объектом на основе XmlWriter.
Документ books.xsl является таблицей стилей. Документ выглядит следующим образом:
<xsname = "note" stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsname = "note" template match="/">
<html>
<head>
<title>Price List</title>
</head>
<body>
<table>
<xsname = "note" apply-templates/>
</table>
</body>
</html>
</xsname = "note" template>
<xsname = "note" template match="bookstore">
<xsname = "note" apply-templates select= "book"/>
</xsname = "note" template>
<xsname = "note" template match="book">
<tr><td>
<xsname = "note" value-of select="title"/>
</td><td>
<xsname = "note" value-of select="price"/>
</td></tr>
</xsname = "note" template>
</xsname = "note" stylesheet>
Ранее упоминался объект XsltArgumentList. Это способ, которым можно объект с методами связать с пространством имен. Когда это сделано, можно вызывать методы во время преобразования. Рассмотрим пример, чтобы понять, как это работает (находится в XPathXSLSample4):
private void button1_Click(object sender, System.EventArgs e) {
// новый XPathDocument
XPathDocument doc=new XPathDocument("..\\..\\..\\booksxpath.xml");
// новый XslTransform
XslTransform transForm=new XslTransform();
transForm.Load("..\\..\\..\\booksarg.xsl");
// новый XmlTextWriter, так как мы создаем новый документ xml
XmlWriter xw=new XmlTextWriter(..\\..\\..\\argSample.xml", null);
// создать XslArgumentList и новый объект BookUtils
XsltArgumentList argBook=new XsltArgumentList();
BookUtils bu=new BookUtils();
// это сообщает список аргументов BookUtils
argBook.AddExtensionObject("urn:ProCSharp", bu);
// новый XPathNavigator
XPathNavigator nav=((IXPathNavigable)doc).CreateNavigator();
// выполнить преобразование
transForm.Transform(nav, argBook, xw);
xw.Close();
}
// простой тестовый класс
public class BookUtils {
public BookUtils() {}
public string ShowText() {
return "This came from the ShowText method!";
}
}
Вывод преобразования (argSample.xml) выглядит так:
<?xml version="1.0"?>
<books>
<discbook>
<booktitle>The Autobiography of Benjamin Franklin</booktitle>
<showtext>This came from the ShowText method!</showLext>
</discbook>
<discbook>
<booktitle>The Confidence Man</booktitle>
<showtext>This came from the ShowText method!</showtext>
</discbook>
<discbook>
<booktitle>The Gorgias</booktitle>
<showtext>This came from the ShowText method!</showtext>
</discbook>
<discbook>