【问题标题】:XSLT 1.0 - Grouping xml elementsXSLT 1.0 - 对 xml 元素进行分组
【发布时间】:2011-10-21 17:34:50
【问题描述】:

需要将系统A的请求转化为fint系统B的请求。

假设我有一个来自系统 A 的 XML 文档,如下所示:

<root>
<Bundle>
    <authors>
        <author>
            <authorID>100</authorID>
            <authorName>Kathisiera</authorName>
        </author>
        <author>
            <authorID>200</authorID>
            <authorName>Bates</authorName>
        </author>
        <author>
            <authorID>300</authorID>
            <authorName>Gavin King</authorName>
        </author>
    </authors>
    <books>
        <book>
            <bookOrderID>1111</bookOrderID>
            <bookName>Head First Java</bookName>
            <bookRefID>100</bookRefID>
        </book>
        <book>
            <bookOrderID>5555</bookOrderID>
            <bookName>Head First Servlets</bookName>
            <bookRefID>200</bookRefID>
        </book>
        <book>
            <bookOrderID>1111</bookOrderID>
            <bookName>Hibernate In Action</bookName>
            <bookRefID>300</bookRefID>
        </book>
    </books>
</Bundle>

我必须把这个请求放入系统B的请求结构中:

<root>
<Bundle>
    <authors>
        <author>
            <authorID>100</authorID>
            <authorName>Kathisiera</authorName>
        </author>
        <author>
            <authorID>300</authorID>
            <authorName>Gavin King</authorName>
        </author>
    </authors>
    <books>
        <book>
            <bookOrderID>1111</bookOrderID>
            <bookName>Head First Java</bookName>
            <bookRefID>100</bookRefID>
        </book>
        <book>
            <bookOrderID>1111</bookOrderID>
            <bookName>Hibernate In Action</bookName>
            <bookRefID>300</bookRefID>
        </book>
    </books>
</Bundle>
<Bundle>
    <authors>
        <author>
            <authorID>200</authorID>
            <authorName>Bates</authorName>
        </author>
    </authors>
    <books>
        <book>
            <bookOrderID>5555</bookOrderID>
            <bookName>Head First Servlets</bookName>
            <bookRefID>200</bookRefID>
        </book>
    </books>
</Bundle>

首先,我必须根据bookOrderIDbook 分组到Bundle 中。然后通过将bookRefIDauthorID 进行比较,将author 分组到Bundle 中。

我尝试使用 xslt 的key() generate-id() 函数。但无法得到预期的结果。

请帮助我解决问题。

【问题讨论】:

    标签: xml xslt xpath


    【解决方案1】:
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:output method="xml" indent="yes"/>
    
        <xsl:key name="k" match="book" use="bookOrderID"/>
        <xsl:key name="a" match="author" use="authorID"/>
    
        <xsl:template match="/root">
            <xsl:copy>
                <xsl:apply-templates select="//books"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="books">
    
            <xsl:apply-templates select="book[generate-id(.) = generate-id(key('k', bookOrderID))]"/>
    
        </xsl:template>
    
        <xsl:template match="book">
            <Bundle>
                <authors>
                    <xsl:apply-templates select="key('a', key('k', bookOrderID)/bookRefID)"/>
                </authors>
    
                <books>
                    <xsl:copy-of select="key('k', bookOrderID)"/>
                </books>
            </Bundle>
        </xsl:template>
    
        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
    
    </xsl:stylesheet>
    

    输入:

    <root>
        <Bundle>
            <authors>
                <author>
                    <authorID>100</authorID>
                    <authorName>Kathisiera</authorName>
                </author>
                <author>
                    <authorID>200</authorID>
                    <authorName>Bates</authorName>
                </author>
                <author>
                    <authorID>300</authorID>
                    <authorName>Gavin King</authorName>
                </author>
            </authors>
            <books>
                <book>
                    <bookOrderID>1111</bookOrderID>
                    <bookName>Head First Java</bookName>
                    <bookRefID>100</bookRefID>
                </book>
                <book>
                    <bookOrderID>5555</bookOrderID>
                    <bookName>Head First Servlets</bookName>
                    <bookRefID>200</bookRefID>
                </book>
                <book>
                    <bookOrderID>1111</bookOrderID>
                    <bookName>Hibernate In Action</bookName>
                    <bookRefID>300</bookRefID>
                </book>
            </books>
        </Bundle>
    </root>
    

    输出:

    <root>
        <Bundle>
            <authors>
                <author>
                    <authorID>100</authorID>
                    <authorName>Kathisiera</authorName>
                </author>
                <author>
                    <authorID>300</authorID>
                    <authorName>Gavin King</authorName>
                </author>
            </authors>
            <books>
                <book>
                    <bookOrderID>1111</bookOrderID>
                    <bookName>Head First Java</bookName>
                    <bookRefID>100</bookRefID>
                </book>
                <book>
                    <bookOrderID>1111</bookOrderID>
                    <bookName>Hibernate In Action</bookName>
                    <bookRefID>300</bookRefID>
                </book>
            </books>
        </Bundle>
        <Bundle>
            <authors>
                <author>
                    <authorID>200</authorID>
                    <authorName>Bates</authorName>
                </author>
            </authors>
            <books>
                <book>
                    <bookOrderID>5555</bookOrderID>
                    <bookName>Head First Servlets</bookName>
                    <bookRefID>200</bookRefID>
                </book>
            </books>
        </Bundle>
    </root>
    

    【讨论】:

      【解决方案2】:

      这是一种方法:

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output indent="yes"/>
      
        <xsl:key name="kBook" match="book" use="bookOrderID" />
      
        <xsl:template match="node() | @*">
          <xsl:copy>
            <xsl:apply-templates select="node() | @*" />
          </xsl:copy>
        </xsl:template>
      
        <xsl:template match="root">
          <xsl:apply-templates mode="bundle" select="Bundle/books/book[
            generate-id()
            =
            generate-id(key('kBook', bookOrderID)[1])
          ]" />
        </xsl:template>
      
        <xsl:template match="book" mode="bundle">
          <xsl:variable name="bookGroup" select="key('kBook', bookOrderID)" />
          <Bundle>
            <authors>
              <xsl:copy-of select="//author[authorID = $bookGroup/bookRefID]" />
            </authors>
            <books>
              <xsl:copy-of select="$bookGroup" />
            </books>
          </Bundle>
        </xsl:template>
      </xsl:stylesheet>
      

      这将使用&lt;xsl:key&gt; 将书籍按其bookOrderID 分组。

      之后,它使用 = 运算符的属性来查找所有相关的 autors:= 运算符将两侧的 所有 节点相互比较。将其视为节点集的一种“内部连接”。这样您就可以使用简单的&lt;xsl:copy-of&gt; 复制正确的节点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多