2016-08-30 69 views
0

我是XSLT新手,正試圖將以下XML轉換爲下一個XML。我已經評論了第二個XML中需要的重大更改。XSLT幫助 - 將屬性轉換爲元素並重命名元素

有2度主要的改變:

1)由於節點2元件名重複,我要重命名的第二次出現。 2)我希望itemName屬性每個成爲一個元素。 2a)對於[客戶ID] itemValue,我需要在將其轉換爲元素時將其重命名爲'CustomerID'。

總之,我希望原件在瀏覽器中呈現後轉換爲更像表格的柱狀結構。

<requestStatus> 
<node1> 
    <clientId>4634</clientId> 
    <affiliateId>0</affiliateId> 
    <contactId>144756</contactId> 
    <requestId>64086</requestId> 
    <transNumber>F27A6A65</transNumber> 
    <status>11</status> 
    <paymentType>D</paymentType> 
    <amount>1.99</amount> 
    <contactEmail>[email protected]</contactEmail> 
    <templateName>Payment Form 2</templateName> 
    <createdBy>0</createdBy> 
    <paymentCnt>1</paymentCnt> 
    <nextPaymtDate/> 
    <recurringFrequency/> 
    <maxPayments>0</maxPayments> 
    <untilDate/> 
    <node2> 
     <node2> 
      <paymtId>56991</paymtId> 
      <paidAmount>1.99</paidAmount> 
      <paymentMethod>C</paymentMethod> 
      <paymentSeq>1</paymentSeq> 
      <submissionDate>08/04/2016</submissionDate> 
      <creditCardType>V</creditCardType> 
      <creditCardNumber>1111</creditCardNumber> 
      <cardHolder>Ronald McDonald</cardHolder> 
      <expirationMonth>1</expirationMonth> 
      <expirationYear>2017</expirationYear> 
      <achRequestId>0</achRequestId> 
      <accountNumber/> 
      <accountType/> 
      <depositType/> 
      <achSubmissionDate/> 
      <achEffectiveDate/> 
     </node2> 
    </node2> 
    <node3> 
     <node4> 
      <itemName>[FirstName]</itemName> 
      <itemValue>Ronald</itemValue> 
     </node4> 
     <node4> 
      <itemName>[LastName]</itemName> 
      <itemValue>McDonald</itemValue> 
     </node4> 
     <node4> 
      <itemName>[Email]</itemName> 
      <itemValue>[email protected]</itemValue> 
     </node4> 
     <node4> 
      <itemName>[Amount]</itemName> 
      <itemValue>1.99</itemValue> 
     </node4> 
     <node4> 
      <itemName>Customer ID</itemName> 
      <itemValue>CUSTOMER1</itemValue> 
     </node4> 
     <node4> 
      <itemName>Invoice Numbers</itemName> 
      <itemValue>INV10001,INV10002</itemValue> 
     </node4> 
    </node3> 
</node1> 
</requestStatus> 


    To this: 

<requestStatus> 
<node1> 
    <clientId>4634</clientId> 
    <affiliateId>0</affiliateId> 
    <contactId>144756</contactId> 
    <requestId>64086</requestId> 
    <transNumber>F27A6A65</transNumber> 
    <status>11</status> 
    <paymentType>D</paymentType> 
    <amount>1.99</amount> 
    <contactEmail>[email protected]</contactEmail> 
    <templateName>Payment Form 2</templateName> 
    <createdBy>0</createdBy> 
    <paymentCnt>1</paymentCnt> 
    <nextPaymtDate/> 
    <recurringFrequency/> 
    <maxPayments>0</maxPayments> 
    <untilDate/> 
    <node2> 
     <node2b> <!-- since node2 element was repeated, rename this as node2b --> 
      <paymtId>56991</paymtId> 
      <paidAmount>1.99</paidAmount> 
      <paymentMethod>C</paymentMethod> 
      <paymentSeq>1</paymentSeq> 
      <submissionDate>08/04/2016</submissionDate> 
      <creditCardType>V</creditCardType> 
      <creditCardNumber>1111</creditCardNumber> 
      <cardHolder>Ronald McDonald</cardHolder> 
      <expirationMonth>1</expirationMonth> 
      <expirationYear>2017</expirationYear> 
      <achRequestId>0</achRequestId> 
      <accountNumber/> 
      <accountType/> 
      <depositType/> 
      <achSubmissionDate/> 
      <achEffectiveDate/> 
     </node2b> 
    </node2> 
    <node3> 
     <FirstName>Ronald</FirstName> <!-- each itemName attribute to become a unique Element --> 
     <LastName>McDonald</LastName> 
     <Email>[email protected]</Email> 
     <Amount>1.99</Amount> 
     <CustomerID>CUSTOMER1</CustomerID> 
     <InvoiceNumbers>INV10001,INV10002</InvoiceNumbers> 
    </node3> 
</node1> 

+1

你不想編號的節點名稱,你嚴重不。重新考慮你的佈局。 – Tomalak

+1

實際的XML不會 - 爲了便於查看而暫時將其編號。 – user3769185

+0

我也不贊同這一點。人們將爲沒有任何好處的編號元素編寫解決方案 - 並且您的XML不難遵循任何一種方式。 – Tomalak

回答

1

我不能完全肯定您確切的要求,但在這樣的情況下,如果只轉換XML的一部分,它通常是最好的開始與identity transform

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

然後,您只需要爲希望轉換的節點編寫模板。因此,例如,重命名node2node2b你這樣做......

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

node2/node2匹配確保只有孩子node2匹配,而不是父母。當然,將這些替換爲您的實際元素名稱。

對於node4元素,你可以使用xsl:element元素,屬性值模板,共同創造新的元素,基於另一個值

<xsl:element name="{translate(itemName, '[] ', '')}"> 
     <xsl:value-of select="itemValue" /> 
    </xsl:element> 

translate功能在這裏會從名稱去掉指定的符號。難道itemName不是一個元素,而不是屬性。

試試這個XSLT作爲首發:

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

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

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

    <xsl:template match="node4"> 
     <xsl:element name="{translate(itemName, '[] ', '')}"> 
      <xsl:value-of select="itemValue" /> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet>