2012-02-20 74 views
0

下面是document_1.xml如何使用xslt从文档中减少排序的价值?

<products> 
    <product> 
     <name>Pen</name> 
     <Quantity>10</Quantity> 
    </product> 
    <product> 
     <name>Pencil</name> 
     <Quantity>20</Quantity> 
    </product> 
    <product> 
     <name>Bag</name> 
     <Quantity>25</Quantity> 
    </product> 
</products> 

document_2.xml

<products> 
    <product> 
     <name>Pen</name> 
     <Quantity>30</Quantity> 
    </product> 

    <product> 
     <name>Pencil</name> 
     <Quantity>5</Quantity> 
    </product> 
    <product> 
     <name>Bag</name> 
     <Quantity>2</Quantity> 
    </product> 
</products> 

document.xml

<products> 
</products> 

下面是我的XSL,我曾经参加document_1.xmldocument_2.xmldocument.xml

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 

<xsl:template match="/products"> 
<xsl:copy> 
<xsl:apply-templates select="document('document_1.xml')/*/product"/> 
<xsl:apply-templates select="document('document_2.xml')/*/product"/> 
</xsl:copy> 
</xsl:template> 

<xsl:template match="@* | node()"> 
<xsl:copy> 
<xsl:apply-templates select="@* | node()"> 
</xsl:apply-templates> 
</xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

我需要一个像下面

  1. 排序输出由数量ASC
  2. 和独特<name>以最小的控管数量

    <products> 
        <product> 
         <name>Bag</name> 
         <Quantity>2</Quantity> 
        </product> 
        <product> 
         <name>Pencil</name> 
         <Quantity>5</Quantity> 
        </product> 
        <product> 
         <name>Pen</name> 
         <Quantity>10</Quantity> 
        </product> 
    

+0

您发布的输出在我看来像document_2。XML只有这样排序单个文件应该很容易。然而你的文字说你想加入两份文件。确切地说,你想添加数量(例如,你可以得到'')? – 2012-02-20 12:08:41

+0

需要加入两个文件,并采取最佳价值。因为有些原因会导致价格较低,首先是文件 – user475464 2012-02-20 12:26:56

+0

请解释什么是“最佳”价值的标准。如果产品有两种数量,您希望在结果文档中使用哪一种数量? – 2012-02-20 12:30:17

回答

0

这个简单的变换

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kProdByName" match="product" use="name"/> 

<xsl:variable name="vallProds" select= 
"document('file:///c:/temp/delete/document_1.xml')/*/* 
| 
    document('file:///c:/temp/delete/document_2.xml')/*/* 
"/> 

<xsl:template match="/*"> 
    <xsl:variable name="vrtfProds"> 
    <xsl:apply-templates select="$vallProds"> 
    <xsl:sort select="name"/> 
    <xsl:sort select="Quantity" data-type="number"/> 
    </xsl:apply-templates> 
    </xsl:variable> 

    <products> 
    <xsl:for-each select="msxsl:node-set($vrtfProds)"> 
    <xsl:copy-of select= 
    "*[generate-id() = generate-id(key('kProdByName', name)[1])]"/> 
    </xsl:for-each> 
    </products> 
</xsl:template> 

<xsl:template match="product"> 
    <xsl:copy-of select="."/> 
</xsl:template> 
</xsl:stylesheet> 

适用于任何XML文档(可能是document.xml中,但这不使用),并具有两个提供的文件驻留在:c:\temp\delete\document_1.xmlc:\temp\delete\document_1.xml

产生想要的,正确的结果

<products> 
    <product> 
     <name>Bag</name> 
     <Quantity>2</Quantity> 
    </product> 
    <product> 
     <name>Pen</name> 
     <Quantity>10</Quantity> 
    </product> 
    <product> 
     <name>Pencil</name> 
     <Quantity>5</Quantity> 
    </product> 
</products> 

说明

  1. 排序两个文件联盟的product元素由两个键nameQuantity

  2. 提取从上述步骤1制备的RTF(Result Tree Fragment)的正则树和由name执行productMuenchian grouping

0

用户此代码为排序

<xsl:for-each select="products/product"> 
     <xsl:sort select="Quantity"/> 
     <tr> 
     <td><xsl:value-of select="name"/></td> 
     <td><xsl:value-of select="Quantity"/></td> 
     </tr> 
    </xsl:for-each> 
+0

如何采取不同的? – user475464 2012-02-20 12:01:45

+0

正在为你排序吗? – 2012-02-20 12:21:03

+0

像下面它的工作 user475464 2012-02-20 12:25:10

0

下面是一个示例XSLT 1.0利用所述exsl:node-set扩展函数大多数处理器支持的:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exsl="http://exslt.org/common" 
    exclude-result-prefixes="exsl"> 

    <xsl:param name="doc1-url" select="'document1.xml'"/> 
    <xsl:param name="doc2-url" select="'document2.xml'"/> 

    <xsl:variable name="doc1" select="document($doc1-url)"/> 
    <xsl:variable name="doc2" select="document($doc2-url)"/> 

    <xsl:output indent="yes"/> 

    <xsl:key name="k1" match="product" use="name"/> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="products"> 
    <xsl:copy> 
     <xsl:variable name="joined-products"> 
     <xsl:copy-of select="$doc1//product | $doc2//product"/> 
     </xsl:variable> 
     <xsl:variable name="grouped-products"> 
     <xsl:apply-templates select="exsl:node-set($joined-products)/product[generate-id() = generate-id(key('k1', name)[1])]" mode="group"/> 
     </xsl:variable> 
     <xsl:apply-templates select="exsl:node-set($grouped-products)/product"> 
     <xsl:sort select="Quantity" data-type="number"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="product" mode="group"> 
    <xsl:copy> 
     <xsl:copy-of select="name"/> 
     <Quantity> 
     <xsl:for-each select="key('k1', name)"> 
      <xsl:sort select="Quantity" data-type="number"/> 
      <xsl:if test="position() = 1"> 
      <xsl:value-of select="Quantity"/> 
      </xsl:if> 
     </xsl:for-each> 
     </Quantity> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

我收到错误消息:Namespace'http://exslt.org/common'不包含任何函数。 – user475464 2012-02-20 15:30:14

+0

您使用哪种XSLT处理器?如果是MSXML,则将'xmlns:exsl =“http://exslt.org/common”'更改为'xmlns:ms =“urn:schemas-microsoft-com:xslt”',然后当然在我使用' exsl:node-set'你需要使用'ms:node-set'。最后使用'exclude-result-prefixes =“ms”'。 – 2012-02-20 16:02:20