2013-04-23 31 views
0

我有一個輸入xml,我必須將元素分組,轉換貨幣格式並刪除名稱空間以添加新的名稱空間。 我已經爲每個提到的操作創建了3個XSLT程序,如果通過提供第一個到第二個XSLT的輸出,一個接一個單獨執行,那麼最終結果是正確的。 但是,我想將所有XSLT模板合併到一個XSLT轉換文檔中。 合併時,我沒有得到所需的輸出xml,而是每個節點都添加了命名空間,並且分組失控而沒有格式化貨幣格式。 示例XML是:如何將多個XSL合併爲單個XSLT信息?

<?xml version="1.0" encoding="UTF-8"?> 
<ns1:Root_Users xmlns:ns1="http://test.com/Users"> 
    <Users> 
     <Id>111</Id> 
     <Name>aaa</Name> 
     <Division>HR</Division> 
     <Salary>1000</Salary> 
    </Users> 
    <Users> 
     <Id>222</Id> 
     <Name>bbb</Name> 
     <Division>FD</Division> 
     <Salary>2000</Salary> 
    </Users> 
    <Users> 
     <Id>333</Id> 
     <Name>ccc</Name> 
     <Division>HR</Division> 
     <Salary>3000</Salary> 
    </Users> 
    <Users> 
     <Id>444</Id> 
     <Name>ddd</Name> 
     <Division>FD</Division> 
     <Salary>4000</Salary> 
    </Users> 
    <Users> 
     <Id>555</Id> 
     <Name>eee</Name> 
     <Division>IT</Division> 
     <Salary>5000</Salary> 
    </Users> 
</ns1:Root_Users> 

我用下面的XSLT轉換實現了輸出。

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

    <!-- Grouping the Users for each Division --> 
    <xsl:key name="GroupKey" match="Users" use="Division"/> 
    <xsl:template match="/*"> 
     <Root_Users> 
      <xsl:apply-templates/> 
     </Root_Users> 
    </xsl:template> 
    <xsl:template match="Users[generate-id()=generate-id(key('GroupKey',Division)[1])]"> 
     <Department name="{Division}"> 
      <xsl:copy-of select="key('GroupKey',Division)"/> 
     </Department> 
    </xsl:template> 
    <xsl:template match="Users[not(generate-id()=generate-id(key('GroupKey',Division)[1]))]"/> 

    <!-- Converting Salary to Denmark Currency Format --> 
    <xsl:decimal-format name="DenmarkCurrencyFormat" grouping-separator="." decimal-separator=","/> 
    <xsl:template match="/*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="//Salary"> 
     <xsl:copy> 
      <xsl:value-of select="format-number(., 'kr ###.###.###,00', 'DenmarkCurrencyFormat')"/> 
     </xsl:copy> 
    </xsl:template> 


    <!-- Removing and Adding new Namespace to Root --> 
    <xsl:template match="/*"> 
    <xsl:element name="{local-name()}" namespace="http://test.com/Department"> 
      <xsl:apply-templates select="@* | node()" /> 
     </xsl:element> 
    </xsl:template> 
    <xsl:template match="@*"> 
     <xsl:attribute name="{local-name()}"> 
      <xsl:value-of select="." /> 
     </xsl:attribute> 
    </xsl:template> 
    <xsl:template match="text() | comment() | processing-instruction()"> 
     <xsl:copy /> 
    </xsl:template> 

</xsl:stylesheet> 

當施加到輸入XML,我得到以下輸出XML:

<Root_Users xmlns="http://test.com/Department"> 
    <Department xmlns="" name="HR"> 
     <Users xmlns:ns1="http://test.com/Users"> 
      <Id>111</Id> 
      <Name>aaa</Name> 
      <Division>HR</Division> 
      <Salary>1000</Salary> 
     </Users> 
     <Users xmlns:ns1="http://test.com/Users"> 
      <Id>333</Id> 
      <Name>ccc</Name> 
      <Division>HR</Division> 
      <Salary>3000</Salary> 
     </Users> 
    </Department> 
    <Department xmlns="" name="FD"> 
     <Users xmlns:ns1="http://test.com/Users"> 
      <Id>222</Id> 
      <Name>bbb</Name> 
      <Division>FD</Division> 
      <Salary>2000</Salary> 
     </Users> 
     <Users xmlns:ns1="http://test.com/Users"> 
      <Id>444</Id> 
      <Name>ddd</Name> 
      <Division>FD</Division> 
      <Salary>4000</Salary> 
     </Users> 
    </Department> 
    <Department xmlns="" name="IT"> 
     <Users xmlns:ns1="http://test.com/Users"> 
      <Id>555</Id> 
      <Name>eee</Name> 
      <Division>IT</Division> 
      <Salary>5000</Salary> 
     </Users> 
    </Department> 
</Root_Users> 

但是所期望的輸出是如下所述。

<Root_Users xmlns="http://test.com/Department"> 
    <Department name="HR"> 
     <Users> 
      <Id>111</Id> 
      <Name>aaa</Name> 
      <Division>HR</Division> 
      <Salary>kr 1.000,00</Salary> 
     </Users> 
     <Users> 
      <Id>333</Id> 
      <Name>ccc</Name> 
      <Division>HR</Division> 
      <Salary>kr 3.000,00</Salary> 
     </Users> 
    </Department> 
    <Department name="FD"> 
     <Users> 
      <Id>222</Id> 
      <Name>bbb</Name> 
      <Division>FD</Division> 
      <Salary>kr 2.000,00</Salary> 
     </Users> 
     <Users> 
      <Id>444</Id> 
      <Name>ddd</Name> 
      <Division>FD</Division> 
      <Salary>kr 4.000,00</Salary> 
     </Users> 
    </Department> 
    <Department name="IT"> 
     <Users> 
      <Id>555</Id> 
      <Name>eee</Name> 
      <Division>IT</Division> 
      <Salary>kr 5.000,00</Salary> 
     </Users> 
    </Department> 
</Root_Users> 

請幫我得到所需的xml。我非常接近,但無法找到究竟導致問題的原因。 非常感謝您的指點。

回答

1

您的解決方案是在正確的軌道上 - 2周主要的事情,我注意到:

  1. 我通過下面我的解決方案的第二到最後一個模板周圍多餘的命名空間的問題了;還有其他方法可以做到這一點,但今晚我的腦海裏就是這樣。 :)
  2. 請注意<xsl:decimal-format>指令需要在頂層。

當這個XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<ns1:Root_Users xmlns:ns1="http://test.com/Users"> 
    <Users> 
    <Id>111</Id> 
    <Name>aaa</Name> 
    <Division>HR</Division> 
    <Salary>1000</Salary> 
    </Users> 
    <Users> 
    <Id>222</Id> 
    <Name>bbb</Name> 
    <Division>FD</Division> 
    <Salary>2000</Salary> 
    </Users> 
    <Users> 
    <Id>333</Id> 
    <Name>ccc</Name> 
    <Division>HR</Division> 
    <Salary>3000</Salary> 
    </Users> 
    <Users> 
    <Id>444</Id> 
    <Name>ddd</Name> 
    <Division>FD</Division> 
    <Salary>4000</Salary> 
    </Users> 
    <Users> 
    <Id>555</Id> 
    <Name>eee</Name> 
    <Division>IT</Division> 
    <Salary>5000</Salary> 
    </Users> 
</ns1:Root_Users> 

......想要的結果產生:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://test.com/Department" 
    version="1.0"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:decimal-format 
    name="DenmarkCurrencyFormat" 
    grouping-separator="." 
    decimal-separator=","/> 

    <xsl:key 
    name="kUserByDivision" 
    match="Users" 
    use="Division"/> 

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

    <xsl:template match="/*"> 
    <Root_Users> 
     <xsl:apply-templates 
     select="*[generate-id() = 
        generate-id(key('kUserByDivision', Division)[1])]"/> 
    </Root_Users> 
    </xsl:template> 

    <xsl:template match="Users"> 
    <Department name="{Division}"> 
     <xsl:for-each select="key('kUserByDivision', Division)"> 
     <Users> 
      <xsl:apply-templates/> 
     </Users> 
     </xsl:for-each> 
    </Department> 
    </xsl:template> 

    <xsl:template match="Users/*"> 
    <xsl:element name="{name()}"> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="Salary/text()"> 
    <xsl:value-of 
     select="concat('kr ', 
        format-number(., 
            '###.###,00', 
            'DenmarkCurrencyFormat'))"/> 
    </xsl:template> 
</xsl:stylesheet> 

......是對所提供的XML應用

<Root_Users xmlns="http://test.com/Department"> <Department name="HR"> <Users> <Id>111</Id> <Name>aaa</Name> <Division>HR</Division> <Salary>kr 1.000,00</Salary> </Users> <Users> <Id>333</Id> <Name>ccc</Name> <Division>HR</Division> <Salary>kr 3.000,00</Salary> </Users> </Department> <Department name="FD"> <Users> <Id>222</Id> <Name>bbb</Name> <Division>FD</Division> <Salary>kr 2.000,00</Salary> </Users> <Users> <Id>444</Id> <Name>ddd</Name> <Division>FD</Division> <Salary>kr 4.000,00</Salary> </Users> </Department> <Department name="IT"> <Users> <Id>555</Id> <Name>eee</Name> <Division>IT</Division> <Salary>kr 5.000,00</Salary> </Users> </Department> </Root_Users> 
+0

完美!這就是我所看到的。 :)非常感謝..因此,在定義任何模板之前,我們首先需要提及小數格式和鍵。無關的命名空間需要更改,並且需要使用模板添加命名空間,而不是定義爲process-instruction。 – CatchLight 2013-04-23 14:46:55