Как сделать сортировку меньшим значением из документа, используя xslt? - PullRequest
0 голосов
/ 20 февраля 2012

Ниже document_1.xml

<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.xml и document_2.xml с document.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>
    

Ответы [ 3 ]

0 голосов
/ 20 февраля 2012

Вот пример 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 голосов
/ 20 февраля 2012

Это простое преобразование :

<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.xml и c:\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 элементов объединения двух документов по двум ключам : name и Quantity.

  2. Извлечение регулярного дерева из RTF ( Фрагмент дерева результатов ), созданного на шаге 1. выше и выполняющего Мюнхенская группировка из product по name.

0 голосов
/ 20 февраля 2012

Используйте этот код для сортировки

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...