需要将请求从系统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>
首先,我必须根据book
在Bundle
内对bookOrderID
进行分组。然后将author
与Bundle
进行比较,将bookRefID
内的authorID
分组。
我尝试使用xslt的key() generate-id()
函数。但无法得到预期的结果。
请帮我解决问题。
答案 0 :(得分: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>
答案 1 :(得分:0)
这是一种方法:
<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>
这会根据bookOrderID
使用<xsl:key>
对书籍进行分组。
之后,它使用=
运算符的属性来查找所有相关的autors:=
运算符将两侧的所有节点相互比较。可以将其视为节点集的一种“内部联接”。这样,您可以使用简单的<xsl:copy-of>
复制正确的节点。