2010-05-05 131 views
5

我正在嘗試學習XSLT,但我最好以實例爲榜樣。我想爲模式轉換執行一個簡單的模式。我如何在一次通行證中執行此轉換(我目前的解決方案使用兩次通行證並失去了客戶的原始訂單)?如何在單個for-each中選擇多個節點XSLT

來源:

<?xml version="1.0" encoding="UTF-8"?> 
<sampleroot> 

<badcustomer> 
    <name>Donald</name> 
    <address>Hong Kong</address> 
    <age>72</age> 
</badcustomer> 

<goodcustomer> 
    <name>Jim</name> 
    <address>Wales</address> 
    <age>22</age> 
</goodcustomer> 

<goodcustomer> 
    <name>Albert</name> 
    <address>France</address> 
    <age>51</age> 
</goodcustomer> 

</sampleroot> 

要:

<?xml version="1.0" encoding="UTF-8"?> 
<records> 

<record id="customer"> 
    <name>Donald</name> 
    <address>Hong Kong</address> 
    <age>72</age> 
    <customertype>bad</customertype> 
</record> 

<record id="customer"> 
    <name>Jim</name> 
    <address>Wales</address> 
    <age>22</age> 
    <customertype>good</customertype> 
</record> 

<record id="customer"> 
    <name>Albert</name> 
    <address>France</address> 
    <age>51</age> 
    <customertype>good</customertype> 
</record> 

</records> 

我已經這樣解決了方式(我失去客戶的訂單,我想我要解析的文件多次:

<?xml version='1.0'?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/sampleroot"> 

    <records> 

     <xsl:for-each select="goodcustomer"> 
      <record id="customer"> 
       <name><xsl:value-of select="name" /></name> 
       <address><xsl:value-of select="address" /></address> 
       <age><xsl:value-of select="age" /></age> 
       <customertype>good</customertype> 
      </record> 
     </xsl:for-each> 

     <xsl:for-each select="badcustomer"> 
      <record id="customer"> 
       <name><xsl:value-of select="name" /></name> 
       <address><xsl:value-of select="address" /></address> 
       <age><xsl:value-of select="age" /></age> 
       <customertype>bad</customertype> 
      </record> 
     </xsl:for-each> 

    </records> 
    </xsl:template> 
</xsl:stylesheet> 

請有人幫助我正確的XSLT構造,我只需要使用一個單一的解析(每個只有一個)?

感謝,

克里斯

+0

好問題Chris(+1)。看到我的答案是一個好的解決方案。 :) – 2010-05-05 17:42:21

回答

6

這是一個很好的做法XSLT避免使用<xsl:for-each>儘可能

這裏有一個簡單的解決方案,利用這個原理

<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="/*"> 
    <records> 
    <xsl:apply-templates/> 
    </records> 
</xsl:template> 

<xsl:template match="badcustomer | goodcustomer"> 
    <record> 
    <xsl:apply-templates/> 
    <customertype> 
    <xsl:value-of select="substring-before(name(), 'customer')"/> 
    </customertype> 
    </record> 
</xsl:template> 
</xsl:stylesheet> 

請注意

  1. 只有模板和<xsl:apply-templates>使用。

  2. 必要時使用身份規則及其覆蓋。這是最基本的XSLT設計模式之一。

+0

謝謝,我可以要求最後一條信息。如果我希望通過原始XML模式的屬性,我將如何調整xslt以使其工作? <名myattribute = 「的AttributeValue」>唐納德 <地址myattribute2 = 「attributevalue2」>香港 Chris 2010-05-06 10:11:17

+0

@克里斯:請,請問這是一個新的問題,搭配不當格式化的代碼/ xml。另外,您正在錯誤地使用「模式」一詞。實際上,您引用的是「源XML文檔」或該文檔類型的模式實例。 – 2010-05-06 12:51:08

+0

感謝您提供的信息並糾正我錯誤使用「模式」。我想出瞭如何解決後續問題,所以我現在不會提出新的問題。 – Chris 2010-05-06 17:42:16