如何使用xml params通过XSLT过滤XML

时间:2009-07-08 18:05:22

标签: xslt

这是我的输入XML:

<Books>
  <Book>
    <BookId>1</BookId>
    <Des>Dumm1</Des>
    <Comments/>
    <OrderDateTime>04/06/2009 12:37</OrderDateTime>
  </Book>
  <Book>
    <BookId>2</BookId>
    <Des>Dummy2</Des>
    <Comments/>
    <OrderDateTime>04/07/2009 12:37</OrderDateTime>
  </Book>
  <Book>
    <BookId>3</BookId>
    <Des>Dumm12</Des>
    <Comments/>
    <OrderDateTime>05/06/2009 12:37</OrderDateTime>
  </Book>
  <Book>
    <BookId>4</BookId>
    <Des>Dummy2</Des>
    <Comments/>
    <OrderDateTime>06/07/2009 12:37</OrderDateTime>
  </Book>
</Books>

我传递了一个XML参数,我的输入XML是

<BookIDs>
  <BookID>2</BookID>
  <BookID>3</BookID>
</BookIDs>

我的输出应该像

<Books>
  <Book>
    <BookId>2</BookId>
    <Des>Dummy2</Des>
    <Comments/>
    <OrderDateTime>04/07/2009 12:37</OrderDateTime>
  </Book>
  <Book>
    <BookId>3</BookId>
    <Des>Dumm12</Des>
    <Comments/>
    <OrderDateTime>05/06/2009 12:37</OrderDateTime>
  </Book>
</Books>

如何使用XSLT完成此操作?

1 个答案:

答案 0 :(得分:0)

这适用于Saxon 6.5.5 ......

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
    <xsl:param name="nodeset">
        <BookIDs><BookID>2</BookID><BookID>3</BookID></BookIDs>
    </xsl:param>

    <xsl:template match="/Books">
        <Books>
            <xsl:variable name="Copy">
                <wrap>
                    <xsl:copy-of select="Book"/>
                </wrap>
            </xsl:variable>
            <xsl:for-each select="$nodeset/BookIDs/BookID">
                <xsl:copy-of select="$Copy/wrap/Book[BookId=current()]"/>
            </xsl:for-each>
        </Books>
    </xsl:template>
</xsl:stylesheet>

纯XSLT解决方案虽然很脆弱。子查询谓词不起作用,也没有键。它取决于param被识别为一个节点集 - 我无法通过动态值(与我的示例中的默认值相反)实现,即使使用exsl:node-set也是如此。这也是浪费,因为它复制了源文档中的所有Book元素。

XSLT 2.0中可能有更好的解决方案。或者,如果您使用其他语言/工具启动转换,可能会有更好的方法。另一种可能性可能包括使用exsl:document加载源文档或参数。