2017-05-16 26 views
0

我已經經歷了很少有關重複元素以及如何使用xsl標識模板的線程。但我的要求是重複大部分元素與幾個需要轉換的字段。在XSLT 2.0中獲取重複元素並進行少量元素轉換

這是我的輸入:

<?xml version="1.0" encoding="UTF-8"?> 
<Roots xmlns="urn:com.mydish/extps"> 
    <Root> 
     <Worker>100</Worker> 
     <Group></Group> 
     <Amount>1165851.81</Amount> 
     <Currency>USD</Currency> 
     <Check>201705091204</Check> 
     <File_Name>1.pdf</File_Name> 
    </Root> 
    <Root> 
     <Worker>20</Worker> 
     <Group></Group> 
     <Amount>231456.41</Amount> 
     <Currency>USD</Currency> 
     <Check>201705091204</Check> 
     <File_Name>2.pdf</File_Name> 
    </Root> 
</Roots> 

輸出必須是:

<?xml version="1.0" encoding="UTF-8"?> 
<Roots xmlns="urn:com.mydish/extps"> 
    <Root> 
     <Worker>C10</Worker> 
     <Group>Group1</Group> 
     <Amount>1165851.81</Amount> 
     <Currency>USD</Currency> 
     <Check>201705091204</Check> 
     <File_Name>1.pdf</File_Name> 
    </Root> 
    <Root> 
     <Worker>C20</Worker> 
     <Group>Group2</Group> 
     <Amount>231456.41</Amount> 
     <Currency>USD</Currency> 
     <Check>201705091204</Check> 
     <File_Name>2.pdf</File_Name> 
    </Root> 
</Roots> 

所以,邏輯取決於輸入工人長度,輸出工人和組字段進行改造。

如果輸入Worker長度爲3位數,則輸出Worker將爲C,前兩位數字(C10)和Group將爲Group1。如果輸入工作者長度是2位數,然後連接C輸出Worker像(C20)和Group將是Group2。

其餘部分必須與輸入相同。

如何轉換? 下面的一個正確嗎?我知道這不會按原樣工作。

<Worker> 
    <xsl:value-of select="if string-length(Worker)='3' then concat('C',substring(Worker,1,2)) else concat('C',Worker)" /> 
</Worker> 
<Group> 
    <xsl:value-of select="if string-length(Worker)='3' then 'Group1' else 'Group2'" /> 
</Group>  

回答

0

嘗試下面的腳本:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:my="urn:com.mydish/extps" 
    xpath-default-namespace="urn:com.mydish/extps"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="Worker"> 
    <xsl:copy> 
     <xsl:value-of select="if (string-length() = 3) 
     then concat('C', substring(., 1, 2)) 
     else concat('C', .)" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Group"> 
    <xsl:copy> 
     <xsl:value-of select="if (string-length(../Worker) = 3) 
     then 'Group1' else 'Group2'" /> 
    </xsl:copy> 
    </xsl:template> 

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

你是相當接近正確的解決方案。

我添加了命名空間處理並對代碼做了輕微的修改。

也許你應該讀一點學習:

  • 關於命名空間的處理,對於的XPath表達式
  • 設置一個默認命名空間的,
  • 一個當前對象的概念(.)模板內部和 它的值是什麼,
  • 如何指的是兄弟對象(例如, Worker element from Group template。
+0

謝謝,這是工作。當然,會學習你指出的主題。它確實有幫助。 – user3836593

0

對於Worker,你可以做簡單:

<xsl:template match="Worker"> 
    <xsl:copy> 
     <xsl:text>C</xsl:text> 
     <xsl:value-of select="substring(., 1, 2)"/> 
    </xsl:copy> 
</xsl:template> 

對於Group,你只需要幾個語法更正:

<xsl:template match="Group"> 
    <xsl:copy> 
     <xsl:value-of select="if (string-length(../Worker)=3) then 'Group1' else 'Group2'" /> 
    </xsl:copy> 
</xsl:template> 

這是除了恆等變換當然是模板。

+0

或者,對於Group使用兩個模板: Group1