XSLT选择XML消息的一部分

XSLT选择XML消息的一部分,xml,xslt,Xml,Xslt,我正在努力寻找XML消息提取问题的解决方案。 我看到的是一条与以下XML消息类似的消息: <Orders xmlns="http://AU.InputOrders"> <Order> <OrderRef>D04004451</OrderRef> <OrderQty>5</OrderQty> </Order> <Order> <OrderRef>D04004451</OrderRef&

我正在努力寻找XML消息提取问题的解决方案。 我看到的是一条与以下XML消息类似的消息:

<Orders xmlns="http://AU.InputOrders">
<Order>
<OrderRef>D04004451</OrderRef>
<OrderQty>5</OrderQty>
</Order>
<Order>
<OrderRef>D04004451</OrderRef>
<OrderQty>1</OrderQty>
</Order>
<Order>
<OrderRef>D04004452</OrderRef>
<OrderQty>1</OrderQty>
</Order>
<Order>
<OrderRef>D04004452</OrderRef>
<OrderQty>4</OrderQty>
</Order>
<Order>
<OrderRef>D04004452</OrderRef>
<OrderQty>2</OrderQty>
</Order>
</Orders>

D04004451
5.
D04004451
1.
D04004452
1.
D04004452
4.
D04004452
2.
我只需要一个XSLT来获取这一点:

<Orders xmlns="http://AU.InputOrders">
<Order>
<OrderRef>D04004451</OrderRef>
<OrderQty>5</OrderQty>
</Order>
<Order>
<OrderRef>D04004451</OrderRef>
<OrderQty>1</OrderQty>
</Order>
</Orders>

D04004451
5.
D04004451
1.


D04004452
1.
D04004452
4.
D04004452
2.
换句话说,我需要根据OrderRef元素值检索订单部件

谢谢

尝试了以下两种解决方案,两种方法都有效。 确实找到了另一个同样有效的解决方案。它不使用OrderRef,而是使用Order元素的位置。但这一个正在做我需要的

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns0="http://AU.InputOrders">
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
   <xsl:element name="Orders" namespace="http://AU.InputOrders">
   <xsl:copy-of select="ns0:Orders/ns0:Order[position() &gt;= 1 and position() &lt;=2]"/>
   </xsl:element>
</xsl:template>
</xsl:stylesheet>


谢谢。

这里有一个XSLT 1.0解决方案,它通过EXSLT扩展函数
exsl:document
将每个@OrderRef组输出到一个单独的文档中(例如,“d0404452.xml”):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:au="http://AU.InputOrders"
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl"
    version="1.0">

    <xsl:key name="kOR" match="au:Order" use="au:OrderRef"/>

    <xsl:template match="/">
        <xsl:for-each select="//au:Order[ generate-id(.) = generate-id(key('kOR', au:OrderRef)[1] ) ]">
            <xsl:call-template name="handle-group">
                <xsl:with-param name="order-ref" select="au:OrderRef"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="handle-group">
        <xsl:param name="order-ref"/>
        <xsl:variable name="fn" select="concat($order-ref,'.xml')"/>
        <exsl:document
            href="{$fn}"
            method="xml"
            indent="yes">
            <xsl:element name="Orders" namespace="http://AU.InputOrders">
                <xsl:for-each select="//au:Order[au:OrderRef=$order-ref]">
                    <xsl:copy-of select="."/>
                </xsl:for-each>
            </xsl:element>
        </exsl:document>
    </xsl:template>

</xsl:stylesheet>


如果您有XSLT 2.0处理器,那么可以使用
而不是

这里有一个相当简单的样式表,可以满足您的要求。(该参数使用默认值,但可以重写。)



如果需要进行额外的处理,请使用
xsl:apply templates
替换
xsl:copy的
;这不是你的要求吗?您的解决方案仅在
Order
元素您恰好需要成为
Orders
中的前两个元素时才有效。这是真的,但后来我意识到,如果使用Order元素位置而不是OrderRef,解决我的问题会更好。我在这里发布了使用固定位置的解决方案,但在现实生活中,我通过代码中的System.String.Format传递这些位置。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:au="http://AU.InputOrders"
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl"
    version="1.0">

    <xsl:key name="kOR" match="au:Order" use="au:OrderRef"/>

    <xsl:template match="/">
        <xsl:for-each select="//au:Order[ generate-id(.) = generate-id(key('kOR', au:OrderRef)[1] ) ]">
            <xsl:call-template name="handle-group">
                <xsl:with-param name="order-ref" select="au:OrderRef"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="handle-group">
        <xsl:param name="order-ref"/>
        <xsl:variable name="fn" select="concat($order-ref,'.xml')"/>
        <exsl:document
            href="{$fn}"
            method="xml"
            indent="yes">
            <xsl:element name="Orders" namespace="http://AU.InputOrders">
                <xsl:for-each select="//au:Order[au:OrderRef=$order-ref]">
                    <xsl:copy-of select="."/>
                </xsl:for-each>
            </xsl:element>
        </exsl:document>
    </xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:au="http://AU.InputOrders">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:param name="orderRef" select="'D04004451'"/>

    <xsl:template match="/*">
        <xsl:copy>
            <xsl:copy-of select="au:Order[au:OrderRef=$orderRef]"/>         
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>