我有以下 XML 有效負載:
<?xml version="1.0" encoding="utf8" ?>
<Output>
<Error>
<Status>0</Status>
<Details>No errors</Details>
</Error>
<Synopsis>
<Count>451</Count>
</Synopsis>
<BankAccounts>
<BankAccount AcctNo="103" CustName="Frank" BalanceAmount="" Inactive="N" NoOfAccounts="1" >
<Addresses>
<Address>ABC</Address>
<Address>XYZ</Address>
</Addresses>
</BankAccount>
<BankAccount AcctNo="101" CustName="Jane" BalanceAmount="10005" Inactive="N" NoOfAccounts="1" >
<Addresses>
<Address>LMN</Address>
<Address>QWE</Address>
</Addresses>
</BankAccount>
</BankAccounts>
</Output>
我需要將其轉換為以下內容:
<?xml version="1.0" encoding="UTF-8"?>
<Output>
<Count>451</Count>
<?xml-multiple bankAccounts?>
<bankAccounts>
<acctNo>103</acctNo>
<custName>Frank</custName>
<balanceAmount/>
<inactive>N</inactive>
<noOfAccounts>1</noOfAccounts>
<?xml-multiple Address?>
<Address>ABC</Address>
<Address>XYZ</Address>
</bankAccounts>
<bankAccounts>
<acctNo>101</acctNo>
<custName>Jane</custName>
<balanceAmount>10005</balanceAmount>
<inactive>N</inactive>
<noOfAccounts>1</noOfAccounts>
<?xml-multiple Address?>
<Address>LMN</Address>
<Address>QWE</Address>
</bankAccounts>
</Output>
我是 XSLT 的業余愛好者,通過查找 SO 并在這里提出問題,不知何故能夠提出如下 XSLT。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Identity template, copies everything as is -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- breakdown attributes of BankAccount into child elements -->
<xsl:template match="BankAccount/@*">
<xsl:element name="{lower-case(substring(name(), 1, 1))}{substring(name(), 2)}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<!-- Drop 'Synopsis' element NOT children AND insert a PI at the end of this operation -->
<xsl:template match="Synopsis" >
<xsl:apply-templates/>
<xsl:processing-instruction name="xml-multiple">
bankAccounts
</xsl:processing-instruction>
</xsl:template>
<!-- This will drop 'Result/Header' element and its children -->
<xsl:template match="Output/Error" />
<!-- This will drop 'BankAccounts' element BUT preserve its children -->
<xsl:template match="BankAccounts">
<xsl:apply-templates/>
</xsl:template>
<!-- rename element 'BankAccount' to 'bankAccounts' -->
<xsl:template match="BankAccount">
<bankAccounts>
<xsl:apply-templates select="@* | node()" />
</bankAccounts>
</xsl:template>
<!-- Drop 'Addresses' element and insert PI first inside 'Addresses' -->
<xsl:template match="Addresses" >
<xsl:processing-instruction name="xml-multiple">
Address
</xsl:processing-instruction>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
這似乎確實有效,但這是我的疑問:
#1 上述 XSL 中是否有任何錯誤/非性能?應該避免的事情?
#2 為什么需要身份模板?我嘗試洗掉它,但它似乎搞砸了 o/p ?
#3 每條指令是否掃描整個 XML 檔案?我想知道是否有一種“鏈接”方法,可以將一個 XSLT 操作的 o/p 饋送到下一個 xslt 操作?
#4 在將“BankAccount”元素的屬性分解為子元素時使用了從另一個問題粘貼的函式副本,但我真的不明白為什么需要子字串?我猜它試圖只處理第一個字母
謝謝
uj5u.com熱心網友回復:
#1 上述 XSL 中是否有任何錯誤/非性能?應該避免的事情?
我注意到的主要事情是您不能依賴屬性的順序:輸出中的元素可能以不同的順序結束,它取決于實作。
#2 為什么需要身份模板?我嘗試洗掉它,但它似乎搞砸了 o/p ?
您正在呼叫 apply-templates 來處理一些您沒有明確模板規則的節點(例如地址元素和空白文本節點)。您的后備模板規則與默認(內置)后備規則不同。
#3a 是否每條指令都掃描整個 XML 檔案?
每個 apply-templates 指令都選擇一組要處理的節點(默認情況下,當前節點的子節點),并且從概念上講,樣式表中的所有模板規則都被檢查以查看其中哪些最適合處理每個這些節點。(實際上,XSLT 處理器可能有更好的策略)。
#3b 我想知道是否有一種方法可以“鏈接”其中一個 XSLT 操作的 o/p 可以饋送到下一個 xslt 操作?
是的,但這是一個全新的主題。搜索 XSLT 管道。
#4 在將“BankAccount”元素的屬性分解為子元素時使用了從另一個問題粘貼的函式副本,但我真的不明白為什么需要子字串?我猜它試圖只處理第一個字母
您正在將名稱的第一個字符轉換為小寫,并原樣復制字串的其余部分。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/466245.html
