使用xslt在单独的xml文件中匹配元素,然后打印兄弟

时间:2014-05-20 08:36:49

标签: xml xslt xpath

如何在两个xml文档之间查找匹配元素,然后打印一个兄弟的兄弟?例如:

customer.xml

<customers>
  <customer>
    <name>John Smith</name>
    <orderid>1234</orderid>
  </customer>
  <customer>
    <name>Sarah White</name>
    <orderid>4321</orderid>
  </customer>
</customers>

orders.xml中

<orders>
  <order>
    <id>1234</id>
    <product>laptop</product>
  </order>
  <order>
    <id>4321</id>
    <product>television</product>
  </order>
</orders>

的Output.xml

<backlog>
  <customer>
    <name>John Smith</name>
    <product>laptop</product>
  </customer>
  <customer>
    <name>Sarah White</name>
    <product>television</product>
  </customer>
</backlog>

我想这样做,以便.xslt像往常一样显示名称,但它应该扫描第二个文档以找到<id>匹配它的<orderid>,然后显示<product>而不是。

显示<name>很容易,但我不确定获取<product>的逻辑是如何工作的。这就是我所拥有的:

<xsl:if test="document('customer.xml')/customers/customer/orderid = document('orders.xml')/orders/order/id">
  <product><xsl:value-of select="document('orders.xml')/orders/order/product" /></product>
</xsl:if>

然而,这给了我以下结果:

<product>laptop television</product>
每个<customer>

2 个答案:

答案 0 :(得分:1)

使用XSLT 2.0,您可以轻松地在文档之间进行交叉引用,例如

<xsl:param name="orders-url" select="'orders.xml'"/>
<xsl:variable name="orders-doc" select="document($orders-url)"/>

<xsl:key name="order" match="order" use="id"/>

<xsl:template match="customer">
  <xsl:copy>
    <xsl:copy-of select="name, key('order', orderid, $orders-doc)/product"/>
  </xsl:copy>
</xsl:template>

然后还添加

<xsl:template match="customers">
  <backlog>
    <xsl:apply-templates/>
  </backlog>
</xsl:template>

你已经完成了。

使用XSLT 1.0,您也可以使用密钥,但需要例如。

<xsl:template match="customer">
  <xsl:copy>
    <xsl:copy-of select="name"/>
    <xsl:variable name="id" select="orderid"/>
    <xsl:for-each select="$orders-doc">
      <xsl:copy-of select="key('order', $id)/product"/>
  </xsl:copy>
</xsl:template>

答案 1 :(得分:1)

尝试以下样式表:

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

    <xsl:output indent="yes"/>

    <xsl:variable name="lookup" select="document('orders.xml')"/>

    <xsl:template match="/">
        <backlog>
            <xsl:for-each select="customers/customer">
                <xsl:variable name="ID" select="orderid"></xsl:variable>
                <xsl:copy>
                    <xsl:copy-of select="name"/>
                    <xsl:copy-of select="$lookup/orders/order/id[.=$ID]/following-sibling::product"></xsl:copy-of>
                </xsl:copy>
            </xsl:for-each>
        </backlog>
    </xsl:template>    

</xsl:stylesheet>