2012-05-31 76 views
0

我是XSLT世界的新手,請耐心等待。 我有一個Web服務的XML輸出結構如下:這可以在XSLT中完成嗎?

<NotificationListResponse> 
    <MessageReceiver ID=15> 
     <Services> 
      <Service ID=40> 
       <...Other Tags Per Service ...> 
      </Service> 
      <Service ID=38> 
       <...Other Tags Per Service ...> 
      </Service> 
     </Services> 
    </MessageReceiver> 
    <MessageReceiver ID=18> 
     <Services> 
      <Service ID=40> 
       <...Other Tags Per Service ...> 
      </Service> 
      <Service ID=38> 
       <...Other Tags Per Service ...> 
      </Service> 
     </Services> 
    </MessageReceiver> 
</NotificationListResponse> 

而且我想變成這個東西是這樣的:

<NotificationListResponse> 
    <Services> 
     <Service ID=40> 
      <Receivers> 
      <MessageReceiver ID=15> 
       <...Other Tags Per Service ...> 
      </MessageReceiver> 
      <MessageReceiver ID=18> 
       <...Other Tags Per Service ...> 
      </MessageReceiver> 
      </Receivers> 
      </Service> 
      <Service ID=38> 
      <Receivers> 
      <MessageReceiver ID=15> 
       <...Other Tags Per Service ...> 
      </MessageReceiver> 
      <MessageReceiver ID=18> 
       <...Other Tags Per Service ...> 
      </MessageReceiver> 
      </Receivers> 
      </Service> 
    </Services> 
</NotificationListResponse> 

我希望這是非常明顯的。我想要做的是按服務進行分段,在Web服務響應中,主要分段由接收方進行。

這甚至可以在XSLT中完成,而不會將XML解壓縮到對象中並在代碼中進行轉換?我們的主要編程語言是C#,以防相關。

+0

答案是肯定的。搜索Muenchian分組,或直接閱讀:http://www.jenitennison.com/xslt/grouping/muenchian.html –

回答

0

這樣的事情可能有點羅嗦,可以改進,但通過msxsl在c#中工作。正如其他人所說,只是看着分組以不同的方式:

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

     <xsl:template match="/NotificationListResponse"> 
      <NotificationListResponse> 
      <Services> 
       <xsl:for-each select=".//Service"> 
        <xsl:variable name="id" select="@ID"/> 
        <xsl:if test="count(preceding::Service[$id]) &lt; 2"> 
         <Service ID="{$id}"> 
          <Receivers> 
           <xsl:for-each select="//Service[@ID=$id]"> 
            <MessageReciever> 
             <xsl:attribute name="ID"> 
              <xsl:value-of select="ancestor::MessageReceiver/@ID"/> 
             </xsl:attribute> 
             <xsl:copy-of select="*"/> 
            </MessageReciever> 
           </xsl:for-each> 
          </Receivers> 
         </Service> 
        </xsl:if> 
       </xsl:for-each> 
      </Services> 
      </NotificationListResponse> 
     </xsl:template> 
    </xsl:stylesheet> 
0

反轉這樣的層次結構是一個組的問題的一個例子:因爲任務是找到具有相同ID的所有的messageReceiver元素,根據此值對輸出進行分組。

XSLT 2.0中的分組要比XSLT 1.0容易得多,不過在這兩種情況下,您的標題問題的答案(可以這樣做)是肯定的。但是,解決方案是非常不同的,所以這將有助於瞭解您使用的是哪個版本。

邏輯上爲溶液中的僞碼是在兩種情況下是相同的:

<for each group of Service elements grouped by ID> 
    <Service ID=ID> 
    <for each Service in the group> 
     <process the ancestor MessageReceiver/> 
    </ 
    </ 
</ 

在XSLT 2.0外觀爲<xsl:for-each-group>元件。在XSLT 1.0中,查找關於「Muenchian分組」的教程