Использовать мюнхенскую группировку с переменным набором узлов? - PullRequest
1 голос
/ 01 февраля 2011

У меня есть переменная xsl, которая содержит:

<Products>
     <product>
         <productId >1</productId>
          <textdate>11/11/2011</textdate>
          <price>200</price>
      </product>
  <product>
         <productId >6</productId>
          <textdate>11/11/2011</textdate>
          <price>100</price>
      </product>
  <product>
         <productId >1</productId>
          <textdate>16/11/2011</textdate>
          <price>290</price>
      </product>
</Products>

Я хочу перегруппировать продукт следующим образом:

{ product 1 :
11/11/2011 - 200
16/11/2011 - 290 }
{ product 6
11/11/2011 - 100 }

с помощью простого мюнхенского алгоритма это возможно, но я не могу иметь xsl: ключ с соответствием переменной.

1010 * редактировать *

Может быть, я не ясно,

У меня есть этот XML-документ mydocument.xml, который я пытаюсь преобразовать:

<?xml version="1.0" encoding="utf-8" ?>
<root>
   <test>somestuff</test>
</root>

Мой xsl должен выглядеть так:

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="2.0"  xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
  <xsl:output omit-xml-declaration="yes" method="xml" encoding="utf-8" />

<xsl:variable name="MyProductList" select="document('myresultlist.xml')" />    
<xsl:key name="kProdById" match="$MyProductList/product" use="productId"/>
 <xsl:template match=
  "product[generate-id()
          =
           generate-id(key('kProdById',productId)[1])
          ]">

  <xsl:value-of select="concat('&#xA;{product ', productId, ' :')"/>
   <xsl:apply-templates mode="display"
    select="key('kProdById',productId)"/>
}<xsl:text/>
 </xsl:template>

 <xsl:template match="product" mode="display">
  <xsl:value-of select=
  "concat('&#xA;', textdate, ' - ', price)"/>
 </xsl:template>

 <xsl:template match="text()"/>
</xsl:stylesheet>

Когда я помещаю свою переменную $ MyProductList в соответствие, Visual Studio выдает ошибку, и когда я пытаюсь принудительно запустить мой веб-приложение.

Так что я не могу сделать то, что мне объяснил Димитр.

Спасибо за помощь

1 Ответ

2 голосов
/ 01 февраля 2011

В этом преобразовании используется метод группирования Мюнхена в его классической форме:

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

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

 <xsl:template match=
  "product[generate-id()
          =
           generate-id(key('kProdById',productId)[1])
          ]">

  <xsl:value-of select="concat('&#xA;{product ', productId, ' :')"/>
   <xsl:apply-templates mode="display"
    select="key('kProdById',productId)"/>
}<xsl:text/>
 </xsl:template>

 <xsl:template match="product" mode="display">
  <xsl:value-of select=
  "concat('&#xA;', textdate, ' - ', price)"/>
 </xsl:template>

 <xsl:template match="text()"/>
</xsl:stylesheet>

при применении к предоставленному документу XML, требуемый, правильный результат получается :

{product 1 :
11/11/2011 - 200
16/11/2011 - 290
}
{product 6 :
11/11/2011 - 100
}

ОБНОВЛЕНИЕ : ОП показал больше информации и объяснил, что проблема (в его коде) заключается в следующих двух строках:

<xsl:variable name="MyProductList" select="document('myresultlist.xml')" />
<xsl:key name="kProdById" match="$MyProductList/product" use="productId"/>

Решение : Просто используйте:

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

Всякий раз, когда вы хотите сослаться на клавишу kProdById в функции key(), убедитесь, что требуемый документ актуален . В более сложных случаях это делается в XSLT 1.0 следующим образом:

<!-- Temporarily switch to the document to be indexed -->
<xsl:for-each select="document('myresultlist.xml')">
  <!-- Use here the key() function -->
</xsl:for-each>

<!-- Resume working with the main document here -->

Вот то же решение, которое теперь применяется к документу (его верхнему элементу), содержащемуся в переменной:

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

    <my:doc>
        <Products>
            <product>
                <productId >1</productId>
                <textdate>11/11/2011</textdate>
                <price>200</price>
            </product>
            <product>
                <productId >6</productId>
                <textdate>11/11/2011</textdate>
                <price>100</price>
            </product>
            <product>
                <productId >1</productId>
                <textdate>16/11/2011</textdate>
                <price>290</price>
            </product>
        </Products> 
     </my:doc>

     <xsl:variable name="vDoc" select="document('')/*/my:doc/*"/>

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

    <xsl:template match="/">
      <xsl:apply-templates select="$vDoc"/>
    </xsl:template>

    <xsl:template match=
       "product[generate-id()
               =
                generate-id(key('kProdById',productId)[1])
                ]">
        <xsl:value-of select="concat('&#xA;{product ', productId, ' :')"/>
        <xsl:apply-templates mode="display"
             select="key('kProdById',productId)"/> }
        <xsl:text/>
    </xsl:template>

    <xsl:template match="product" mode="display">
        <xsl:value-of select=
           "concat('&#xA;', textdate, ' - ', price)"/>
    </xsl:template>
    <xsl:template match="text()"/>
</xsl:stylesheet>

когда это преобразование применяется к любому документу (не используется), снова получается желаемый результат:

{product 1 :
11/11/2011 - 200
16/11/2011 - 290 }

{product 6 :
11/11/2011 - 100 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...