сортировать и отображать документы, основанные на отрасли, которая выбирается из каждого объекта - PullRequest
1 голос
/ 22 сентября 2011

У меня есть XML-файл, который структурирован так:

<documents>
<item>
    <title>Document Title</title>
    <customer>Customer Name1</customer>
    <description>Description 1 here</description>
    <image height="100" width="100"></image>
    <link filetype="pdf" language="English">/documents/document.pdf</link>
    <industry>Industry name 1</industry>
</item>
<item>
    <title>Document Title 2</title>
    <customer>Customer Name 2</customer>
    <description>Description 2 here</description>
    <image height="100" width="100"></image>
    <link filetype="pdf" language="English">/documents/document2.pdf</link>
    <industry>Industry name 2</industry>
</item>

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

<h2>Industry name 1</h2>
<div class="doc">
<h3>Document Title</h3>
<p>Description 1 here <a href="/documents/document.pdf">Download!</a></p>
</div>

<h2>Industry name 2</h2>
<div class="doc">
<h3>Document Title 2</h3>
<p>Description 2 here <a href="/documents/document.pdf">Download!</a></p>
</div>

Где я полностью озадачен, это то, как я могу динамически получить отрасли из XML, распечатать первый, а затем все документы, относящиеся к этому.промышленность, а затем перейти к второй отрасли, затем к третьей и четвертой и так далее.Я начинаю задумываться, возможно ли это вообще, когда я считаю, что XSL должен на самом деле хранить каждый «тег» отрасли от каждого и сравнивать их, чтобы увидеть, есть ли он у него.Если это произойдет, он не должен распечатывать его, а просто печатать остальную информацию.

Я бы предпочел не изменять схему файла XML, поскольку он используется повсеместно и уже служит другим целям.Но я понимаю, что это может быть.

Обратите также внимание, что файл полностью не отсортирован.Последний добавленный файл находится вверху, независимо от отраслевого «тега», связанного с ним.Однако это можно изменить.

Для меня это крепкий орешек, если даже можно использовать чистый XSL в качестве парсера?

1 Ответ

1 голос
/ 23 сентября 2011

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

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kItemByInd" match="item"
  use="industry"/>

 <xsl:template match=
  "item[generate-id()
       =
        generate-id(key('kItemByInd', industry)[1])
       ]
  ">
  <h2><xsl:value-of select="industry"/></h2>

  <xsl:apply-templates mode="inGroup"
   select="key('kItemByInd', industry)"/>
 </xsl:template>

 <xsl:template match="item"/>

 <xsl:template match="item" mode="inGroup">
   <div class="doc">
     <h3><xsl:value-of select="title"/></h3>
     <p>
       <xsl:value-of select="description"/>
       <a href="{link}"> Download!</a>
     </p>
   </div>
 </xsl:template>
</xsl:stylesheet>

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

<documents>
    <item>
        <title>Document Title</title>
        <customer>Customer Name1</customer>
        <description>Description 1 here</description>
        <image height="100" width="100"></image>
        <link filetype="pdf" language="English">/documents/document.pdf</link>
        <industry>Industry name 1</industry>
    </item>
    <item>
        <title>Document Title 2</title>
        <customer>Customer Name 2</customer>
        <description>Description 2 here</description>
        <image height="100" width="100"></image>
        <link filetype="pdf" language="English">/documents/document2.pdf</link>
        <industry>Industry name 2</industry>
    </item>
    <item>
        <title>Document Title 3</title>
        <customer>Customer Name 3</customer>
        <description>Description 3 here</description>
        <image height="100" width="100"></image>
        <link filetype="pdf" language="English">/documents/document3.pdf</link>
        <industry>Industry name 1</industry>
    </item>
</documents>

дает требуемый, правильный результат :

<h2>Industry name 1</h2>
<div class="doc">
   <h3>Document Title</h3>
   <p>Description 1 here<a href="/documents/document.pdf"> Download!</a>
   </p>
</div>
<div class="doc">
   <h3>Document Title 3</h3>
   <p>Description 3 here<a href="/documents/document3.pdf"> Download!</a>
   </p>
</div>

<h2>Industry name 2</h2>
<div class="doc">
   <h3>Document Title 2</h3>
   <p>Description 2 here<a href="/documents/document2.pdf"> Download!</a>
   </p>
</div>

и отображается в браузере как :

Название отрасли 1

Название документа

Описание 1 здесь Загрузить!

Название документа 3

Описание 3 здесь Загрузить!

Название отрасли 2

Название документа 2

Описание 2 здесь Загрузить!

Объяснение : Метод Мюнхена для группировки .

II.Решение XSLT 2.0 :

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

 <xsl:template match="/*">
  <xsl:for-each-group select="item" group-by="industry">
    <h2><xsl:value-of select="industry"/></h2>
    <xsl:apply-templates select="current-group()"/>
  </xsl:for-each-group>
 </xsl:template>

  <xsl:template match="item">
   <div class="doc">
     <h3><xsl:value-of select="title"/></h3>
     <p>
       <xsl:value-of select="description"/>
       <a href="{link}"> Download!</a>
     </p>
   </div>
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование XSLT 2.0 применяется к тому же XML-документу (см. Выше), снова получается тот же правильный результат .

Пояснение :

  1. <xsl:for-each-group>

  2. current-group()

ОБНОВЛЕНИЕ : В соответствии с запросом OP, здесь есть вариант решения XSLT 1.0, которыйтакже сортирует по industry:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kItemByInd" match="item"
  use="industry"/>

 <xsl:template match="/*">
  <xsl:apply-templates select=
   "item[generate-id()
        =
         generate-id(key('kItemByInd', industry)[1])
        ]
   ">
    <xsl:sort select="industry"/>
   </xsl:apply-templates>

 </xsl:template>

 <xsl:template match="item">
  <h2><xsl:value-of select="industry"/></h2>

  <xsl:apply-templates mode="inGroup"
   select="key('kItemByInd', industry)"/>
 </xsl:template>

 <xsl:template match="item" mode="inGroup">
   <div class="doc">
     <h3><xsl:value-of select="title"/></h3>
     <p>
       <xsl:value-of select="description"/>
       <a href="{link}"> Download!</a>
     </p>
   </div>
 </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...