0

我是 XSLT 世界的新手,所以请多多包涵。我有一个具有以下结构的 Web 服务的 XML 输出:

<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#。

4

2 回答 2

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 分组”的教程

于 2012-05-31T09:42:04.590 回答
0

像这样的东西可能有点罗嗦,可以改进,但可以通过 c# 中的 msxsl 工作。正如其他人所说,只是看待分组的另一种方式:

    <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>
于 2012-05-31T08:40:50.477 回答