2010-10-20 155 views
1

我在w3schools上了解了XSLT和XPath,但它不完全是我想要的。 只有關於轉換XSLT 2 HTML的示例,這很簡單,但我需要XML 2 XML轉換並找不到示例的好教程...我下載了MSXSL.exe,但無法找到使用它來轉換XML的示例... 任何人都可以寫一個示例嗎? 我有customers.xml喜歡:XML 2使用XSLT的XML

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<!--Customers table from Northwind database--> 
<Customers> 
    <Customer CustomerID="ALFKI"> 
    <CompanyName>Alfreds Futterkiste</CompanyName> 
    <Country>Germany</Country> 
    <Orders> 
     <Order OrderID="10643"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
     <Order OrderID="10692"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
     <Order OrderID="10702"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
     <Order OrderID="10835"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
     <Order OrderID="10952"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
     <Order OrderID="11011"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
    </Orders> 
    </Customer> 
    <Customer CustomerID="ANATR"> 
    <CompanyName>Ana Trujillo Emparedados y helados</CompanyName> 
    <Country>Mexico</Country> 
    <Orders> 
     <Order OrderID="10308"> 
     <ShipCity>México D.F.</ShipCity> 
     </Order> 
     <Order OrderID="10625"> 
     <ShipCity>México D.F.</ShipCity> 
     </Order> 
     <Order OrderID="10759"> 
     <ShipCity>México D.F.</ShipCity> 
     </Order> 
     <Order OrderID="10926"> 
     <ShipCity>México D.F.</ShipCity> 
     </Order> 
    </Orders> 
    </Customer> 
</Customers> 

,並試圖生成一個只包含「國家」節點.. 怎麼寫另一個XML?

+0

問得好,+1。看到我的答案兩種解決方案。 :) – 2010-10-20 13:25:50

回答

1

這裏有兩個不同的解決方案:一種簡單的和更復雜的一個只產生了獨特的國家:

.1。獲取所有Country元素:

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

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[not(self::Country)]"> 
    <xsl:apply-templates select="*"/> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉變是在所提供的XML文檔應用,通緝,正確的結果產生

<Country>Germany</Country> 
<Country>Mexico</Country> 

0.2。 找到所有獨特的國家

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:key name="kCountryByVal" match="Country" use="."/> 

<xsl:template match="/"> 
    <xsl:copy-of select= 
     "/*/*/Country[generate-id() 
        = 
        generate-id(key('kCountryByVal',.)[1]) 
        ] 
     "/> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉變被應用在任何XML文檔與所提供的文件,其中一些Country的元件可以具有相同的值的結構,只有一個Country爲每個不同的價值元素生產

隨着所提供的XML文檔,我們仍然得到同樣的結果:

<Country>Germany</Country> 
<Country>Mexico</Country> 
3

完全一樣,您只需要相應地使用output元素的method屬性。

+1

+1,這裏的例子:http://www.w3schools.com/xsl/el_output.asp – Bruno 2010-10-20 12:39:44

3

一些關於這應該工作...

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
    <Countries> 
     <xsl:apply-templates select="//Country" mode="copyNode" /> 
    </Countries> 
    </xsl:template> 

    <xsl:template match="@* | node()" mode="copyNode"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()" mode="copyNode"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

...下面是結果...

<?xml version="1.0" encoding="utf-8"?> 
<Countries> 
    <Country>Germany</Country> 
    <Country>Mexico</Country> 
</Countries> 
+0

猜猜我不需要微軟命名空間,如果我不使用它。 – 2010-10-20 12:43:48

+0

我應該添加這個元素,如果它們存在的話,它將包含''元素的任何子節點。 – 2010-10-20 12:53:07

1

它非常簡單,你只需要編寫XML而不是HTML在你的xslt模板中。

以下(未經測試)應該讓你開始:

<xsl:template match="/"> 
    <Countries> 
    <xsl:apply-templates select="Customers/Customer" /> 
    </Countries> 
</xsl:template> 

<xsl:template match="Customer"> 
    <Country> 
    <xsl:value-of select="Country" /> 
    </Country> 
</xsl:template> 

而且,對於一個XSLT處理器,我衷心推薦的Visual Studio - 它有一個很好的XSLT調試程序,這將幫助你沒有盡頭瞭解您的樣式表。 (我不知道這功能包含在Express版本...)

0

在拉風,這應該是更短的樣式表達這種轉變:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="text()"/> 
    <xsl:template match="@*|/*|Country|Country/text()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<Customers> 
    <Country>Germany</Country> 
    <Country>Mexico</Country> 
</Customers>