Выберите из XML-узла с несколькими элементами категории - PullRequest
2 голосов
/ 14 января 2012

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

<item>
        <link>http://www.threelanews.com/articles/?id=50456</link>
        <category>/General/</category>
        <category>/Technology/</category>
        <category>/Technology/Telecommunications/</category>
        <category>/Technology/Information Technology/Internet/</category>
        <title>Sony debuts handsets at CES</title>
        <description>The Xperia S will be available globally from the first quarter of 2012.&#xD;Sony Ericsson will showcase the first handsets from...</description>
       <pubDate>Tue, 10 Jan 2012 12:11:01 +0200</pubDate>
</item>

Я использую таблицу стилей XSL для преобразования документа.Для каждой группы я сделаю тест, чтобы увидеть, какие элементы принадлежат этой категории, и если в одном из элементов категории есть совпадение, статью следует добавить в html, например:

<xsl:when test="contains(category,'/General/')">
   <div class="news-item" width="100%">
      <div class="news-item-title" width="100%">
          <a href="{$linkUrl}" target="_blank">
             <xsl:value-of select="title"/>
          </a>
      </div>
      <xsl:if test="string-length($imageUrl) &gt; 0">
          <div class="news-item-image">
             <img src="{$imageUrl}" />
          </div>
      </xsl:if>
      <div class="news-item-description">
          <xsl:value-of select="description"/>
      </div>
   </div>
   <div class="clear" />
</xsl:when>

ЗатемСтатья должна быть добавлена ​​в «Генеральную группу».Статьи с несколькими категориями должны появляться в каждой группе, чтобы они были актуальны.Вышеприведенное утверждение будет работать для группы «Общие», но когда я пытаюсь сделать то же самое для «Технологии» или других категорий ниже, эта статья не возвращается.Я обнаружил, что это только соответствие первого элемента.Можно ли как-нибудь сопоставить все элементы категории?

Ответы [ 2 ]

1 голос
/ 14 января 2012

Попробуйте следующие преобразования:

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

    <xsl:template match="/">
        <html>
            <body>
                <h2>Matched Items</h2>
                <xsl:apply-templates select=
                "//item[category/.='/General/']"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="item">
        <div class="news-item" width="100%">
            <div class="news-item-title" width="100%">
                <a href="{linkUrl}" target="_blank">
                    <xsl:value-of select="title"/>
                </a>
            </div>
            <xsl:if test="string-length(imageUrl) &gt; 0">
                <div class="news-item-image">
                    <img src="{imageUrl}" />
                </div>
            </xsl:if>
            <div class="news-item-description">
                <xsl:value-of select="description"/>
            </div>
        </div>
        <div class="clear" />
    </xsl:template>
</xsl:stylesheet>

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

//item[category/.='/General/']

Применение преобразованияк этому документу:

<items>
    <item>
        <link>http://www.threelanews.com/articles/?id=50456</link>
        <category>/General/</category>
        <category>/Technology/</category>
        <category>/Technology/Telecommunications/</category>
        <category>/Technology/Information Technology/Internet/</category>
        <title>Sony debuts handsets at CES</title>
        <description>The Xperia S will be available globally from the first quarter of 2012.&#xD;Sony Ericsson will showcase the first handsets from...</description>
        <pubDate>Tue, 10 Jan 2012 12:11:01 +0200</pubDate>
    </item>
    <item>
        <link>http://www.threelanews.com/articles/?id=50456</link>
        <category>/Technology/</category>
        <category>/Technology/Telecommunications/</category>
        <category>/Technology/Information Technology/Internet/</category>
        <title>Sony debuts handsets at CES</title>
        <description>The Xperia S will be available globally from the first quarter of 2012.&#xD;Sony Ericsson will showcase the first handsets from...</description>
        <pubDate>Tue, 10 Jan 2012 12:11:01 +0200</pubDate>
    </item>
</items>

Дает ожидаемый результат:

<H2>Matched Items</H2>
<DIV class=news-item width="100%">
  <DIV class=news-item-title width="100%"><A href="" target=_blank>Sony debuts handsets at CES</A></DIV>
  <DIV class=news-item-description>The Xperia S will be available globally from the first quarter of 2012. Sony Ericsson will showcase the first handsets from...</DIV>
</DIV>
<DIV class=clear></DIV>
0 голосов
/ 14 января 2012

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

<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="kCategoryByVal" match="category"
  use="substring-before(substring(.,2), '/')"/>

 <xsl:template match=
  "category
     [generate-id()
     =
      generate-id(key('kCategoryByVal',
                      substring-before(substring(.,2), '/')
                      )
                       [1]
                  )
     ]

  ">
  <xsl:variable name="vMainCat" select=
       "substring-before(substring(.,2), '/')"/>

  <h1><xsl:value-of select="$vMainCat"/></h1>

  <xsl:apply-templates mode="inGroup" select=
   "/*/item[category[starts-with(., concat('/', $vMainCat))]]"/>
 </xsl:template>

 <xsl:template match="item" mode="inGroup">
   <div class="news-item" width="100%">
     <div class="news-item-title" width="100%">
       <a href="{link}" target="_blank">
         <xsl:value-of select="title"/>
       </a>
     </div>
      <xsl:apply-templates select="image[@url]" mode="inGroup"/>
     <div class="news-item-description">
      <xsl:value-of select="description"/>
     </div>
   </div>
   <div class="clear" />
 </xsl:template>

 <xsl:template match="image" mode="inGroup">
  <div class="news-item-image">
    <img src="{@url}" />
  </div>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

при применении к этому документу XML (получено из предоставленного, но немного более реалистично):

<items>
    <item>
        <link>http://www.threelanews.com/articles/?id=50456</link>
        <category>/General/</category>
        <category>/Technology/</category>
        <category>/Technology/Telecommunications/</category>
        <category>/Technology/Information Technology/Internet/</category>
        <title>Sony debuts handsets at CES</title>
        <image url="http://www.blogcdn.com/www.engadget.com/media/2011/03/11x0328mar0424.jpg"/>
        <description>The Xperia S will be available globally from the first quarter of 2012.&#xD;Sony Ericsson will showcase the first handsets from...</description>
        <pubDate>Tue, 10 Jan 2012 12:11:01 +0200</pubDate>
    </item>
    <item>
        <link>http://www.threelanews.com/articles/?id=50456</link>
        <category>/Technology/</category>
        <category>/Technology/Telecommunications/</category>
        <category>/Technology/Information Technology/Internet/</category>
        <title>Toshiba produces the next Portege</title>
        <description>The next Portege will be available globally from the first quarter of 2012.&#xD;Sony Ericsson will showcase the first handsets from...</description>
        <pubDate>Tue, 10 Jan 2012 12:11:01 +0200</pubDate>
    </item>
</items>

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

<h1>General</h1>
<div class="news-item" width="100%">
   <div class="news-item-title" width="100%">
      <a href="http://www.threelanews.com/articles/?id=50456" target="_blank">Sony debuts handsets at CES</a>
   </div>
   <div class="news-item-image">
      <img src="http://www.blogcdn.com/www.engadget.com/media/2011/03/11x0328mar0424.jpg"/>
   </div>
   <div class="news-item-description">The Xperia S will be available globally from the first quarter of 2012.&#xD;Sony Ericsson will showcase the first handsets from...</div>
</div>
<div class="clear"/>
<h1>Technology</h1>
<div class="news-item" width="100%">
   <div class="news-item-title" width="100%">
      <a href="http://www.threelanews.com/articles/?id=50456" target="_blank">Sony debuts handsets at CES</a>
   </div>
   <div class="news-item-image">
      <img src="http://www.blogcdn.com/www.engadget.com/media/2011/03/11x0328mar0424.jpg"/>
   </div>
   <div class="news-item-description">The Xperia S will be available globally from the first quarter of 2012.&#xD;Sony Ericsson will showcase the first handsets from...</div>
</div>
<div class="clear"/>
<div class="news-item" width="100%">
   <div class="news-item-title" width="100%">
      <a href="http://www.threelanews.com/articles/?id=50456" target="_blank">Toshiba produces the next Portege</a>
   </div>
   <div class="news-item-description">The next Portege will be available globally from the first quarter of 2012.&#xD;Sony Ericsson will showcase the first handsets from...</div>
</div>
<div class="clear"/>

Объяснение

  1. Все различные основные категории можно найти, используя Мюнхенская группировка .

  2. Для каждой из основных категорий, все элементы item, имеющие category со строковым значением, которое делает элемент в этой основной категории, выводят данные элемента соответствующим образом.

  3. В этом решении делается предположение, что должны быть перечислены только «Основные» категории (начальное имя категории в строке, содержащей категорию и подкатегории).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...