2013-07-11 69 views
0

我正在努力寻找XML消息提取问题的解决方案。 我所拥有的是下面的XML消息的相似:XSLT选择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> 

我需要一个XSLT只得到该位:

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

<Orders xmlns="http://AU.InputOrders"> 
<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> 

换句话说,我需要根据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> 

谢谢。

+0

您的解决方案根本不使用'OrderRef';那不是你的要求之一吗?您的解决方案仅适用于您需要的'Order'元素碰巧是'订单'中的前2个元素。 –

+0

这是真的,但后来我意识到如果我将使用Order元素位置而不是OrderRef,会对我的问题更好。我在这里发布了使用固定位置的解决方案,但在现实生活中,我通过代码中的System.String.Format来传递这些位置。 –

回答

0

这是一个相当简单的样式表,它可以满足你的要求。 (它使用该参数的默认值,但可以覆盖。)

<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> 

如果你需要做额外的处理,更换xsl:copy-ofxsl:apply-templates,添加一个identity transform,并覆盖使用模板来处理特定的件。

0

下面是一个XSLT 1.0溶液,每个@OrderRef组输出到一个单独的文件(例如, “D04004452.xml”)经由EXSLT扩展函数exsl:document

<?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:result-document/>而不是<exsl:document/>