XPath (XML路径语言,XML Path Language)是一种表达式语言,用于从XML文档中选择节点。XSLT(扩展样式表转换语言,Extension Stylesheet Language Transformation)是一种声明性语言,用于将XML文档从一种形式转换为另一种形式。比如说,XSLT可以将XML文档转换成HTML文档。
比较LINQ to XML 和 XPath
原生XML文档
<?xml version="1.0" encoding="utf-8"?>
<Blackjack>
<Player Name="Player 1">
<Statistics>
<AverageAmountLost>-28.125</AverageAmountLost>
<AverageAmountWon>30.681818181818183</AverageAmountWon>
<Blackjacks>1</Blackjacks>
<Losses>8</Losses>44
<NetAverageWinLoss>5.9210526315789478</NetAverageWinLoss>
<NetWinLoss>112.5</NetWinLoss>
<PercentageOfBlackJacks>0.041666666666666664</PercentageOfBlackJacks>
<PercentageOfLosses>33.333333333333329</PercentageOfLosses>
<PercentageOfPushes>16.666666666666664</PercentageOfPushes>
<PercentageOfWins>45.833333333333329</PercentageOfWins>
<Pushes>4</Pushes>
<Surrenders>1</Surrenders>
<TotalAmountLost>-225</TotalAmountLost>
<TotalAmountWon>337.5</TotalAmountWon>
<Wins>11</Wins>
</Statistics>
</Player>
</Blackjack>
使用命名空间
XML文档支持命名空间。如果将下面这个命名空间添加到上面的XML文档中,那么再使用LINQ to XML 查询或是XPath查询中就必须也加上命名空间。
<?xml version="1.0" encoding="utf-8"?>
<jack:Blackjack xmlns:jack="http://www.blackjack.com">
<jack:Player Name="Player 1">
<jack:Statistics>
<jack:AverageAmountLost>-28.125</jack:AverageAmountLost>
<jack:AverageAmountWon>30.681818181818183</jack:AverageAmountWon>
<jack:Blackjacks>1</jack:Blackjacks>
<jack:Losses>8</jack:Losses>
<jack:NetAverageWinLoss>5.9210526315789478</jack:NetAverageWinLoss>
<jack:NetWinLoss>112.5</jack:NetWinLoss>
<jack:PercentageOfBlackJacks>0.041666666666666664</jack:PercentageOfBlackJacks>
<jack:PercentageOfLosses>33.333333333333329</jack:PercentageOfLosses>
<jack:PercentageOfPushes>16.666666666666664</jack:PercentageOfPushes>
<jack:PercentageOfWins>45.833333333333329</jack:PercentageOfWins>
<jack:Pushes>4</jack:Pushes>
<jack:Surrenders>1</jack:Surrenders>
<jack:TotalAmountLost>-225</jack:TotalAmountLost>
<jack:TotalAmountWon>337.5</jack:TotalAmountWon>
<jack:Wins>11</jack:Wins>
</jack:Statistics>
</jack:Player>
</jack:Blackjack>
使用LINQ to XML 和 XPath实现相同功能
private static void UseNamespace()
{
const string filename = "..\\..\\CurrentStatsWithNamespace.xml";
XDocument doc = XDocument.Load(filename);
XNamespace jack = "http://www.blackjack.com";
XElement winLoss1 = doc.Element(jack + "Blackjack").Element(jack + "Player").Element(jack + "Statistics").Element(jack + "NetWinLoss");
Console.WriteLine(winLoss1);
Console.ReadLine();
// 根据文件名创建XmlReader
XmlReader reader = XmlReader.Create(filename);
// 获取根元素
XElement root = XElement.Load(reader);
// NameTable是System.Xml.Nametable类的是一个实例,好友XML文档的元素和属性的原子化名称
XmlNameTable table = reader.NameTable;
// 增加名称空间
XmlNamespaceManager manager = new XmlNamespaceManager(table);
manager.AddNamespace("jack", "http://www.blackjack.com");
XElement winLoss2 =
doc.XPathSelectElement("./jack:Blackjack/jack:Player/jack:Statistics/jack:NetWinLoss",
manager);
Console.WriteLine(winLoss2);
Console.ReadLine();
}
查找子元素
private static void FindChild()
{
const string filename = "..\\..\\CurrentStats.xml";
XElement xml = XElement.Load(filename);
XElement child1 = xml.Element("Player").Element("Statistics").Element("AverageAmountLost");
Console.WriteLine(child1);
Console.ReadLine();
// XPath expression using System.Xml.Linq capabilities
XElement child2 = xml.XPathSelectElement("Player/Statistics/AverageAmountLost");
Console.WriteLine(child2);
Console.ReadLine();
}
查找兄弟元素
private static void FindSibling()
{
const string filename = "..\\..\\CurrentStats.xml";
XElement xml = XElement.Load(filename);
XElement child1 = xml.Element("Player").Element("Statistics").Element("AverageAmountWon");
XElement sibling1 = child1.ElementsAfterSelf().First();
Console.WriteLine(sibling1);
Console.ReadLine();
XElement child2 = xml.XPathSelectElement("Player/Statistics/AverageAmountWon");
XElement sibling2 = child2.XPathSelectElement("following-sibling::*");
Console.WriteLine(sibling2);
Console.ReadLine();
}
过滤元素
private static void FilterOnAttribute()
{
const string filename = "..\\..\\CurrentStats.xml";
XElement xml = XElement.Load(filename);
XElement player1 =
(from elem in xml.Elements("Player")
where elem.Attribute("Name").Value == "Player 1"
select elem).First();
Console.WriteLine(player1);
XElement player2 = xml.XPathSelectElement("Player[@Name='Player 1']");
Console.WriteLine(player2);
Console.ReadLine();
}
比较LINQ to XML 转换和 XSLT
完整XSL样式表文档,当将其应用到前面使用的XML文档上时,就会转换成HTML文档。
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head>
<style type="text/css">
table
{
cellspacing: 0;
cellpadding: 0;
border-top: "1 solid #000000";
border-bottom: "1 solid #000000";
border-right: "1 solid #000000";
border-left: "1 solid #000000";
}
td.Header
{
background-color: "#000111";
color: "#FFFFFF";
border: "1 solid #000000";
}
td.Name
{
background-color: "silver";
border: "1 solid #000000";
}
td.Data
{
text-align: right;
width: 100px;
border-bottom: "1 solid #000000";
}
</style>
</head>
<body>
<table cellspacing="0" cellpadding="0">
<xsl:for-each select="Blackjack/Player/Statistics">
<tr>
<td class="Header">Name</td>
<td class="Header">Value</td>
</tr>
<tr>
<td class="Name">
Average Amount Lost:
</td>
<td class="Data">
<strong>
<xsl:value-of select='format-number(AverageAmountLost, "#.000")' />
</strong>
</td>
</tr>
<tr>
<td class="Name">
Average Amount Won:
</td>
<td class="Data">
<strong>
<xsl:value-of select='format-number(AverageAmountWon, "#.000")'/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Losses:
</td>
<td class="Data">
<strong>
<xsl:value-of select="Losses"/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Blackjacks:
</td>
<td class="Data">
<strong>
<xsl:value-of select="Blackjacks"/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Net Average Win Loss:
</td>
<td class="Data">
<strong>
<xsl:value-of select='format-number(NetAverageWinLoss, "0.000")'/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Net Win Loss:
</td>
<td class="Data">
<strong>
<xsl:value-of select="NetWinLoss"/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Percentage of Blackjacks:
</td>
<td class="Data">
<strong>
<xsl:value-of select='format-number(PercentageOfBlackJacks, "0.000%")'/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Percentage of Losses:
</td>
<td class="Data">
<strong>
<xsl:value-of select='format-number(PercentageOfLosses div 100, "0.000%")' />
</strong>
</td>
</tr>
<tr>
<td class="Name">
Percentage of Pushes:
</td>
<td class="Data">
<strong>
<xsl:value-of select='format-number(PercentageOfPushes div 100, "0.000%")'/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Percentage of Wins:
</td>
<td class="Data">
<strong>
<xsl:value-of select='format-number(PercentageOfWins div 100, "0.000%")'/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Pushes:
</td>
<td class="Data">
<strong>
<xsl:value-of select="Pushes"/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Pushes:
</td>
<td class="Data">
<strong>
<xsl:value-of select="Pushes"/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Surrenders:
</td>
<td class="Data">
<strong>
<xsl:value-of select="Surrenders"/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Total Amount Won or Lost:
</td>
<td class="Data">
<strong>
<xsl:value-of select="TotalAmountLost"/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Total Amount Won:
</td>
<td class="Data">
<strong>
<xsl:value-of select="TotalAmountWon"/>
</strong>
</td>
</tr>
<tr>
<td class="Name">
Wins:
</td>
<td class="Data">
<strong>
<xsl:value-of select="Wins"/>
</strong>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>