XSLT帮助 - 将属性转换为元素并重命名元素

时间:2016-08-30 17:51:22

标签: xml xslt

我是XSLT的新手,我正在尝试将以下XML转换为下一个XML。我评论了第二个XML中需要进行的重大更改。

有两个主要变化:

1)由于node2元素名称重复,我想重命名第二次出现。 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>fmaraicar@linked2pay.com</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>fmaraicar@linked2pay.com</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>fMcDonald@somewhere.com</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>fMcDonald@somewhere.com</Email>
        <Amount>1.99</Amount>
        <CustomerID>CUSTOMER1</CustomerID>  
        <InvoiceNumbers>INV10001,INV10002</InvoiceNumbers>
    </node3>
</node1>

1 个答案:

答案 0 :(得分:1)

我不完全确定您的确切要求,但在这种情况下,您只是在转换XML的一部分,通常最好从identity transform开始

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

然后,您只需要为要转换的节点编写模板。因此,例如,要将node2重命名为node2b,您可以执行此操作...

    <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>