2015-02-10 207 views
2

我不得不組使用Oracle服務總線在XSLT 1.0的XML文檔。嵌套分組使用XSLT muenchian-分組

這是示例輸入文件(簡體):

<?xml version="1.0" encoding="UTF-8"?> 
    <EMailData> 
     <property name="A"> 
      <property name="B"> 
       <property name="C"> 
       <row> 
        <property name="C1"> 
         <value>ValC1</value> 
        </property> 
        <property name="C2"> 
         <value>ValC2</value> 
        </property> 
        <property name="C3"> 
         <value>Valc3</value> 
        </property> 
        <property name="C4"> 
         <value>Valc4</value> 
        </property> 
       </row> 
      </property> 
      <property name="C"> 
       <row> 
        <property name="C1"> 
         <value>ValC1</value> 
        </property> 
        <property name="C2"> 
         <value>ValC2</value> 
        </property> 
        <property name="C3"> 
         <value>Valc3</value> 
        </property> 
        <property name="C4"> 
         <value>Valc4</value> 
        </property> 
       </row> 
      </property> 
      <property name="D"> 
       <row> 
        <property name="D1"> 
         <value>ValD1</value> 
        </property> 
        <property name="D2"> 
         <value>VALd2</value> 
        </property> 
        <property name="D3-InnerElement"> //Need to Group this too 
         <row> 
         <property name="Status"> 
          <value>Status122</value> 
         </property> 
         </row> 
        </property> 
        <property name="D3-InnerElement"> 
         <row> 
         <property name="Status"> 
          <value>Status123</value> 
         </property> 
         </row> 
        </property> 
        <property name="D3-InnerElement"> 
         <row> 
         <property name="Status"> 
          <value>Status124</value> 
         </property> 
         </row> 
        </property> 
       </row> 
      </property> 
      <property name="D"> 
       <row> 
        <property name="D1"> 
         <value>ValD1</value> 
        </property> 
        <property name="D2"> 
         <value>VALd2</value> 
        </property> 
        <property name="D3-InnerElement"> 
         <row> 
         <property name="Status"> 
          <value>Status122</value> 
         </property> 
         </row> 
        </property> 
        <property name="D3-InnerElement"> 
         <row> 
         <property name="Status"> 
          <value>Status123</value> 
         </property> 
         </row> 
        </property> 
        <property name="D3-InnerElement"> 
         <row> 
         <property name="Status"> 
          <value>Status124</value> 
         </property> 
         </row> 
        </property> 
       </row> 
      </property>    
      </property> 
     </property> 
    </EMailData> 

我的XSLT邏輯:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:strip-space elements="*"/> 
<xsl:output indent="yes"/> 

<xsl:key name="group" match="/*/*/*/property" use="@name"/> 

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

<xsl:template match="/*/*/*[property[@name]]"> 
<xsl:copy> 
<xsl:copy-of select="@*"/> 
<xsl:for-each select="*[generate-id() = generate-id(key('group', @name)[1])]"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates select="key('group', @name)/*"/> 
    </xsl:copy> 
</xsl:for-each> 
</xsl:copy> 
</xsl:template> 

<!--Change for Inner Hierarchy--> 

<xsl:key name="inner-group" match="/*/*/*/*/property" use="@name"/> 

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

<xsl:template match="/*/*/*/*[property[@name]]"> 
<xsl:copy> 
<xsl:copy-of select="@*"/> 
<xsl:for-each select="*[generate-id() = generate-id(key('inner-group', @name)[1])]"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates select="key('inner-group', @name)/*"/> 
    </xsl:copy> 
</xsl:for-each> 
</xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

預期O/P

<?xml version="1.0" encoding="UTF-8"?> 
<EMailData> 
    <property name="A"> 
     <property name="B"> 
     <property name="C"> 
      <row> 
       <property name="C1"> 
        <value>ValC1</value> 
       </property> 
       <property name="C2"> 
        <value>ValC2</value> 
       </property> 
       <property name="C3"> 
        <value>Valc3</value> 
       </property> 
       <property name="C4"> 
        <value>Valc4</value> 
       </property> 
      </row> 
      <row> 
       <property name="C1"> 
        <value>ValC1</value> 
       </property> 
       <property name="C2"> 
        <value>ValC2</value> 
       </property> 
       <property name="C3"> 
        <value>Valc3</value> 
       </property> 
       <property name="C4"> 
        <value>Valc4</value> 
       </property> 
      </row> 
     </property> 
     <property name="D"> 
      <row> 
       <property name="D1"> 
        <value>ValD1</value> 
       </property> 
       <property name="D2"> 
        <value>VALd2</value> 
       </property> 
       <property name="D3-InnerElement"> //Need to Group this too 
         <row> 
        <property name="Status"> 
         <value>Status122</value> 
        </property> 
        </row> 
       </property> 
       <property name="D3-InnerElement"> 
        <row> 
        <property name="Status"> 
         <value>Status123</value> 
        </property> 
        </row> 
        <row> 
        <property name="Status"> 
         <value>Status124</value> 
        </property> 
        </row> 
       </property> 
      </row> 
      <row> 
       <property name="D1"> 
        <value>ValD1</value> 
       </property> 
       <property name="D2"> 
        <value>VALd2</value> 
       </property> 
       <property name="D3-InnerElement"> 
        <row> 
        <property name="Status"> 
         <value>Status122</value> 
        </property> 
        </row> 
        <row> 
        <property name="Status"> 
         <value>Status123</value> 
        </property> 
        </row> 
        <row> 
        <property name="Status"> 
         <value>Status124</value> 
        </property> 
        </row> 
       </property> 
      </row> 
     </property> 
     </property> 
    </property> 
</EMailData> 

但D3 -nenerelement沒有分組。告訴我我哪裏出錯了!

O/P對於我的XSLT

<?xml version="1.0" encoding="UTF-8"?> 
<EMailData> 
    <property name="A"> 
     <property name="B"> 
     <property name="C"> 
      <row> 
       <property name="C1"> 
        <value>ValC1</value> 
       </property> 
       <property name="C2"> 
        <value>ValC2</value> 
       </property> 
       <property name="C3"> 
        <value>Valc3</value> 
       </property> 
       <property name="C4"> 
        <value>Valc4</value> 
       </property> 
      </row> 
      <row> 
       <property name="C1"> 
        <value>ValC1</value> 
       </property> 
       <property name="C2"> 
        <value>ValC2</value> 
       </property> 
       <property name="C3"> 
        <value>Valc3</value> 
       </property> 
       <property name="C4"> 
        <value>Valc4</value> 
       </property> 
      </row> 
     </property> 
     <property name="D"> 
      <row> 
       <property name="D1"> 
        <value>ValD1</value> 
       </property> 
       <property name="D2"> 
        <value>VALd2</value> 
       </property> 
       <property name="D3-InnerElement"> //Need to Group this too 
          <row> 
        <property name="Status"> 
         <value>Status122</value> 
        </property> 
        </row> 
       </property> 
       <property name="D3-InnerElement"> 
        <row> 
        <property name="Status"> 
         <value>Status123</value> 
        </property> 
        </row> 
       </property> 
       <property name="D3-InnerElement"> 
        <row> 
        <property name="Status"> 
         <value>Status124</value> 
        </property> 
        </row> 
       </property> 
      </row> 
      <row> 
       <property name="D1"> 
        <value>ValD1</value> 
       </property> 
       <property name="D2"> 
        <value>VALd2</value> 
       </property> 
       <property name="D3-InnerElement"> 
        <row> 
        <property name="Status"> 
         <value>Status122</value> 
        </property> 
        </row> 
       </property> 
       <property name="D3-InnerElement"> 
        <row> 
        <property name="Status"> 
         <value>Status123</value> 
        </property> 
        </row> 
       </property> 
       <property name="D3-InnerElement"> 
        <row> 
        <property name="Status"> 
         <value>Status124</value> 
        </property> 
        </row> 
       </property> 
      </row> 
     </property> 
     </property> 
    </property> 
</EMailData> 

在此先感謝!

+0

除了可以發佈您的預期輸出,你可以在你想做些什麼的話解釋一下嗎?瞭解樣式表需要一段時間。 – 2015-02-10 09:17:04

+0

我只是想組一個元素本身下的特定元素內的所有單獨的行。如在,不重複元素C.只需按行分開它們。這必須進一步完成到一個元素內部。這是哪裏出了問題occurst – HeisenBerg 2015-02-10 09:19:02

+0

沒有足夠的解釋。你能不能詳細說明一下。另外,我沒有看到你的輸入和預期的輸出是同步的,例如,我可以看到'Status133'在你的預期輸出文本節點,而不是輸入。你能解決這個問題嗎? – 2015-02-10 09:23:37

回答

2

而且這裏去使用Muenchian的分組解決方案:

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

<xsl:key name="group" match="property" use="@name"/> 

<xsl:template match="/EMailData/property/property | /EMailData/property/property/property/row"> 
    <xsl:variable name="id" select="generate-id()"/> 
    <xsl:copy> 
     <xsl:copy-of select="@*"/> 
     <xsl:for-each select="property[count(. | key('group', @name)[$id = generate-id(parent::*)][1]) = 1]"> 
      <xsl:copy> 
       <xsl:copy-of select="@*"/> 
       <xsl:apply-templates select="key('group', @name)[$id = generate-id(parent::*)]/*"/> 
      </xsl:copy> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()" /> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 
1

該解決方案不是基於Muenchian的分組,但認爲這將是有益的:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:strip-space elements="*"/> 
<xsl:output method="xml" indent="yes"/> 
<xsl:template match="*[property]"> 
    <xsl:copy> 
     <xsl:copy-of select="@*"/> 
     <xsl:for-each select="property[not(@name = preceding-sibling::property/@name)]"> 
      <xsl:copy> 
       <xsl:copy-of select="@*"/> 
       <xsl:apply-templates select="../property[@name = current()/@name]/*"/> 
      </xsl:copy> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()" /> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

這裏,第二模板是恆等變換模板,用於複製所有屬性和節點。

第一個模板與包含至少一個property子元素的元素相匹配,或者以簡單的詞語「property元素的父代將被@name分組」。 您可能,以及,模板匹配更改爲:

<xsl:template match="/EMailData/property/property | /EMailData/property/property/property/row"> 

for-each是第一property在當前父特定@name值(參見使用preceding-sibling的條件)。 而對於每一次迭代,模板被施加爲與當前(for-each元素的)@name,即,可以通過@name的值分組單親的property元件property元素的所有子元素。

相同的模板被稱爲用於內property元件,分組甚至那些由@name

+0

好工作Lingamurthy。謝謝。它工作正常。你能簡單解釋一下嗎? – HeisenBerg 2015-02-10 11:30:16

+0

雖然我無法想出使用Muenchian的分組方法,但我很高興它幫助你。讓我用一些解釋來編輯我的答案。 – 2015-02-10 11:31:54

+0

@HeisenBerg請使用Muenchian的分組查看我的第二個答案。 – 2015-02-10 12:17:55