【笔记】【LINQ编程技术内幕】第十九章 比较LINQ to XML 与其他XML技术

    技术2025-05-02  11

    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>
    Processed: 0.019, SQL: 9