使用XSLT以特定方式重新排序XML元素

时间:2013-04-02 08:53:10

标签: asp.net xml xslt xslt-1.0

我有两个XSL变量。 1.ProductID

  <prdid>
    <id>8143794</id>
    <id>8143793</id>
    <id>8142229</id>
    <id>8143796</id>
  </prdid>

2.Productxml

    <root>
  <product>
    <estocklevel>0</estocklevel>
    <id>8142229</id>
    <isp_brand extra="isp_brand"></isp_brand>
    <isp_produktserie extra="isp_produktserie"></isp_produktserie>
    <isp_model extra="isp_model"></isp_model>
  </product>
  <product>
    <estocklevel>0</estocklevel>
    <id>8143793</id>
    <isp_brand extra="isp_brand">Leitz</isp_brand>
    <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
    <isp_model extra="isp_model">Bred</isp_model>
  </product> 
  <product>
    <estocklevel>0</estocklevel>
    <id>8143794</id>
    <isp_brand extra="isp_brand">Leitz</isp_brand>
    <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
    <isp_model extra="isp_model">Smal</isp_model>
  </product>
  <product>
    <id>8143796</id>
    <isp_brand extra="isp_brand">Leitz</isp_brand>
    <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
    <isp_model extra="isp_model">Smal</isp_model>
  </product>
</root>

现在我想要的是,在for循环中我希望以prdid XML的顺序获取productxml中的每个产品 像

 <xsl:for-each select="prdid/id">
        <!--i want to get a product node from productxml here which got same id of that in this for loop -->
      <xsl:value-of select="productxml/id"/>
    </xsl:for-each>

3 个答案:

答案 0 :(得分:2)

此转换简短有效

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

 <xsl:variable name="vProds" select=
   "document('file:///c:/temp/delete/products.xml')"/>

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

 <xsl:template match="/*">
  <root><xsl:apply-templates/></root>
 </xsl:template>

 <xsl:template match="id">
  <xsl:variable name="vId" select="."/>
  <xsl:for-each select="$vProds">
   <xsl:copy-of select="key('kProdById', $vId)"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

将其应用于提供的“prdid”XML文档

<prdid>
    <id>8143794</id>
    <id>8143793</id>
    <id>8142229</id>
    <id>8143796</id>
</prdid>

,第二个提供的文档包含在文件中:c:\temp\delete\products.xml

<root>
    <product>
        <estocklevel>0</estocklevel>
        <id>8142229</id>
        <isp_brand extra="isp_brand"></isp_brand>
        <isp_produktserie extra="isp_produktserie"></isp_produktserie>
        <isp_model extra="isp_model"></isp_model>
    </product>
    <product>
        <estocklevel>0</estocklevel>
        <id>8143793</id>
        <isp_brand extra="isp_brand">Leitz</isp_brand>
        <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
        <isp_model extra="isp_model">Bred</isp_model>
    </product>
    <product>
        <estocklevel>0</estocklevel>
        <id>8143794</id>
        <isp_brand extra="isp_brand">Leitz</isp_brand>
        <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
        <isp_model extra="isp_model">Smal</isp_model>
    </product>
    <product>
        <id>8143796</id>
        <isp_brand extra="isp_brand">Leitz</isp_brand>
        <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
        <isp_model extra="isp_model">Smal</isp_model>
    </product>
</root>

产生了想要的正确结果:

<root>
   <product>
      <estocklevel>0</estocklevel>
      <id>8143794</id>
      <isp_brand extra="isp_brand">Leitz</isp_brand>
      <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
      <isp_model extra="isp_model">Smal</isp_model>
   </product>
   <product>
      <estocklevel>0</estocklevel>
      <id>8143793</id>
      <isp_brand extra="isp_brand">Leitz</isp_brand>
      <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
      <isp_model extra="isp_model">Bred</isp_model>
   </product>
   <product>
      <estocklevel>0</estocklevel>
      <id>8142229</id>
      <isp_brand extra="isp_brand"/>
      <isp_produktserie extra="isp_produktserie"/>
      <isp_model extra="isp_model"/>
   </product>
   <product>
      <id>8143796</id>
      <isp_brand extra="isp_brand">Leitz</isp_brand>
      <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
      <isp_model extra="isp_model">Smal</isp_model>
   </product>
</root>

<强>解释

正确使用 keys

这演示了如何使用XSLT 1.0将一个XML文档中的值作为另一个XML文档中节点的键

答案 1 :(得分:1)

我假设“Productxml”是您的输入XML文件。

样式表

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

  <!--
  The order in which you want to process the <product> elements. You could also
  have this in a separate file if you want, and change the document() function
  below to point to that file instead.
  -->
  <my:prdid>
    <id>8143794</id>
    <id>8143793</id>
    <id>8142229</id>
    <id>8143796</id>
  </my:prdid>

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

  <xsl:template match="root">
    <!-- Save reference to the nodeset that contains all <product> children -->
    <xsl:variable name="products" select="product"/>

    <xsl:copy>
      <!--
      For each <id> element in the <my:prdid> element (document('') refers to
      the current stylesheet)...
      -->
      <xsl:for-each select="document('')/*/my:prdid/id">
        <!--
        ...apply the <product> element that has the same id value as this <id>
        element
        -->
        <xsl:apply-templates select="$products[id = current()]"/>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

输入

<root>
  <product>
    <estocklevel>0</estocklevel>
    <id>8142229</id>
    <isp_brand extra="isp_brand"></isp_brand>
    <isp_produktserie extra="isp_produktserie"></isp_produktserie>
    <isp_model extra="isp_model"></isp_model>
  </product>
  <product>
    <estocklevel>0</estocklevel>
    <id>8143793</id>
    <isp_brand extra="isp_brand">Leitz</isp_brand>
    <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
    <isp_model extra="isp_model">Bred</isp_model>
  </product> 
  <product>
    <estocklevel>0</estocklevel>
    <id>8143794</id>
    <isp_brand extra="isp_brand">Leitz</isp_brand>
    <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
    <isp_model extra="isp_model">Smal</isp_model>
  </product>
  <product>
    <id>8143796</id>
    <isp_brand extra="isp_brand">Leitz</isp_brand>
    <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
    <isp_model extra="isp_model">Smal</isp_model>
  </product>
</root>

输出

<root>
  <product>
    <estocklevel>0</estocklevel>
    <id>8143794</id>
    <isp_brand extra="isp_brand">Leitz</isp_brand>
    <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
    <isp_model extra="isp_model">Smal</isp_model>
  </product>
  <product>
    <estocklevel>0</estocklevel>
    <id>8143793</id>
    <isp_brand extra="isp_brand">Leitz</isp_brand>
    <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
    <isp_model extra="isp_model">Bred</isp_model>
  </product>
  <product>
    <estocklevel>0</estocklevel>
    <id>8142229</id>
    <isp_brand extra="isp_brand"/>
    <isp_produktserie extra="isp_produktserie"/>
    <isp_model extra="isp_model"/>
  </product>
  <product>
    <id>8143796</id>
    <isp_brand extra="isp_brand">Leitz</isp_brand>
    <isp_produktserie extra="isp_produktserie">180</isp_produktserie>
    <isp_model extra="isp_model">Smal</isp_model>
  </product>
</root>

答案 2 :(得分:0)

xsl:sort应该是你需要的。 看看这里:

http://www.w3schools.com/xsl/el_sort.asp#gsc.tab=0

编辑1:这应该有效

<xsl:for-each select="//prdid/id">
  <xsl:call-template name="sortedId">
    <xsl:with-param name="id" select="."></xsl:with-param>
  </xsl:call-template>
</xsl:for-each>    


<xsl:template name="sortedId" >
    <xsl:param name="id"></xsl:param>
    <xsl:apply-templates select="//product[id=$id]" />
</xsl:template>

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