Как получить путь изображения для тега <img src="?"> из файла XML - PullRequest
7 голосов
/ 08 августа 2010

Я хотел бы использовать XML-файл

<pics> 
 <pic no="1">c:\pic1.jpg</pic>
 <pic no="2">c:\pic2.jpg</pic>
 <pic no="3">c:\pic3.jpg</pic>
 <pic no="4">c:\pic4.jpg</pic>
 <pic no="5">c:\pic5.jpg</pic>
 ....
</pics>

в HTML-таблице:

<table cellspacing="2" cellpadding="2" border="0">             
    <tr>
    <td><img src="" width="150" height="120" /></td>
    <td><img src="" width="150" height="120" /></td>
    <td><img src="" width="150" height="120" /></td>

   </tr>
   <tr>  
    <td><img src="from xml" width="150" height="120" /></td>
    <td><img src="from xml" width="150" height="120" /></td>
    <td><img src="from xml" width="150" height="120" /></td>
   </tr>
   <tr>
    <td><img src="from xml" width="150" height="120" /></td>
    <td><img src="from xml" width="150" height="120" /></td>
    <td><img src="from xml" width="150" height="120" /></td>
   </tr>                    
</table>

Какой лучший способ сделать это?

Ответы [ 4 ]

3 голосов
/ 08 августа 2010

XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="web_page.xsl"?>
<pics>
  <pic>
   <td>
     <no src="http://farm1.static.flickr.com/160/387667598_ea86c93d81.jpg" width="150" height="120">1</no>
   </td>
   <td>
     <no src="http://farm1.static.flickr.com/160/387667598_ea86c93d81.jpg" width="150" height="120">2</no>
   </td>
   <td>
     <no src="http://farm1.static.flickr.com/160/387667598_ea86c93d81.jpg" width="150" height="120">3</no>
   </td>
  </pic>
  <pic>
   <td>
     <no src="http://motherjones.com/files/legacy/mojoblog/funny-cats-a10.jpg" width="150" height="120">4</no>
  </td>
   <td>
     <no src="http://motherjones.com/files/legacy/mojoblog/funny-cats-a10.jpg" width="150" height="120">5</no>
  </td>
   <td>
     <no src="http://motherjones.com/files/legacy/mojoblog/funny-cats-a10.jpg" width="150" height="120">6</no>
  </td>
  </pic>
</pics>

XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<body>
  <table> 
  <xsl:for-each select="pics/pic">
    <tr>
      <xsl:for-each select="td">
        <td><img>
          <xsl:attribute name="src">
            <xsl:value-of select="no//@src"/>
          </xsl:attribute>
          <xsl:attribute name="width">
            <xsl:value-of select="no//@width"/>
          </xsl:attribute>
          <xsl:attribute name="height">
            <xsl:value-of select="no//@height"/>
          </xsl:attribute>
        </img></td>
      </xsl:for-each>
    </tr>
  </xsl:for-each>
  </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Попробуйте сами (скопируйте и вставьте мой код в соответствующие поля):

2 голосов
/ 08 августа 2010

В предложенном выводе есть ошибка, поскольку элементы <img/> должны иметь атрибуты alt в каждой версии HTML, в которой они присутствуют.

В любом случае следующее делает это, но без тех атрибутов, которые можно сделать из CSS вместо этого (просто чтобы уменьшить размер). Добавление их обратно, если необходимо, тривиально:

<xsl:template match="pics">
    <table>
        <xsl:apply-templates select="pic[position() mod 3 = 1]"/>
    </table>
</xsl:template>
<xsl:template match="pic[position() mod 3 = 1]">
    <tr>
        <td>
            <xsl:if test="2 &gt; count(following-sibling::pic)">
                <xsl:attribute name="colspan">
                    <xsl:value-of select="3 - count(following-sibling::pic)"/>
                </xsl:attribute>
            </xsl:if>
            <img src="{.}" alt="" />
        </td>
        <xsl:apply-templates select="following-sibling::pic[3 &gt; position()]" />
    </tr>
</xsl:template>
<xsl:template match="pic">
    <td><img src="{.}" alt=""/></td>
</xsl:template>

Выше предполагается, что вы хотите, чтобы путь от файла использовался напрямую, добавление кода для его преобразования каким-либо образом (скажем, взятие только последней части пути с использованием substring-after()) не является сложным расширением, предполагая, что указанное преобразование не является Сам не усложняю.

Edit:

Я и ДжонБ идем на дальнейшую территорию, всего этого достаточно, чтобы ответить на оригинальный вопрос.

Добавлено, чтобы дать более полный ответ на вопрос Джона Б. Ниже приведен эквивалентный код, использующий for-each вместо apply-templates. Теоретически и последовательная реализация, и реализация на основе конечного автомата процессора XSLT должны одинаково справляться с этим, хотя на практике вы можете найти различия (если вы скажете, что они отличаются от данного процессора, я бы поставил на него небольшую сумму) немного быстрее с последовательной обработкой и немного медленнее с конечным автоматом, но я бы поставил только очень небольшую сумму).

Обратите внимание, что мы не можем повторно использовать шаблон по умолчанию для рис. С другой стороны, если у нас есть другой шаблон по умолчанию для pic в другом месте (если это было частью гораздо более сложной таблицы стилей), нам не нужно быть умным, чтобы различать их, что является основным временем, когда я лично склонялся бы к каждому.

<xsl:template match="pics">
    <table>
    <xsl:for-each select="pic[position() mod 3 = 1]">
            <tr>
                <td>
                    <xsl:if test="2 &gt; count(following-sibling::pic)">
                        <xsl:attribute name="colspan">
                            <xsl:value-of select="3 - count(following-sibling::pic)"/>
                    </xsl:attribute>
                    </xsl:if>
                    <img src="{.}" alt="" />
                </td>
                <xsl:for-each select="following-sibling::pic[3 &gt; position()]">
                    <td><img src="{.}" alt=""/></td>
                </xsl:for-each>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>
1 голос
/ 08 августа 2010

Использовать XSL.Пример здесь .Кстати, почему у вас там атрибут no?

0 голосов
/ 08 августа 2010

Вот типичное решение, которое соответствует духу XSLT (нет <xsl:for-each>), как можно короче и параметризовано для нужного количества столбцов в таблице.

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

    <xsl:param name="pNumCols" select="3"/>

 <xsl:template match="pics">
  <table cellspacing="2" cellpadding="2" border="0">
   <xsl:apply-templates select="pic[position() mod $pNumCols = 1]"/>
  </table>
 </xsl:template>

 <xsl:template match="pic">
   <tr>
    <xsl:apply-templates mode="process" select=
    "(. | following-sibling::pic)[not(position() > $pNumCols)]"/>
   </tr>
 </xsl:template>

 <xsl:template match="pic" mode="process">
   <td><img src="{.}" width="150" height="120" /></td>
 </xsl:template>
</xsl:stylesheet>

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

<pics>
 <pic no="1">http://col.stb.s-msn.com/i/D7/6A19748C9AA58B938F42099543D2E.jpg</pic>
 <pic no="2">http://col.stb.s-msn.com/i/1F/35A8478AC24EEF95933B5F0E4E394.jpg</pic>
 <pic no="3">http://col.stb.s-msn.com/i/76/3ADA01320CEC8B31D53FACC0C11E.jpg</pic>
 <pic no="4">http://col.stb.s-msn.com/i/92/51BF117987A3279571F06BEB4AE39D.jpg</pic>
 <pic no="5">http://col.stb.s-msn.com/i/9B/9A6E876BA2F7EAE82392C7E7F6C1C.jpg</pic>
 <pic no="6">http://col.stb.s-msn.com/i/50/8CC964E5503A7F61F8AD22A12024.jpg</pic>
 <pic no="7">http://col.stb.s-msn.com/i/C4/F7EF634B7084DA69AAB5AAD05C8922.jpg</pic>
 <pic no="8">http://col.stb.s-msn.com/i/FB/C8367425D67FA391A5E0F8A3E0276B.jpg</pic>
</pics>

желаемый результат получается (см. Также в браузере :)):

<table cellspacing="2" cellpadding="2" border="0">
   <tr>
      <td>
         <img src="http://col.stb.s-msn.com/i/D7/6A19748C9AA58B938F42099543D2E.jpg" width="150" height="120"/>
      </td>
      <td>
         <img src="http://col.stb.s-msn.com/i/1F/35A8478AC24EEF95933B5F0E4E394.jpg" width="150" height="120"/>
      </td>
      <td>
         <img src="http://col.stb.s-msn.com/i/76/3ADA01320CEC8B31D53FACC0C11E.jpg" width="150" height="120"/>
      </td>
   </tr>
   <tr>
      <td>
         <img src="http://col.stb.s-msn.com/i/92/51BF117987A3279571F06BEB4AE39D.jpg" width="150" height="120"/>
      </td>
      <td>
         <img src="http://col.stb.s-msn.com/i/9B/9A6E876BA2F7EAE82392C7E7F6C1C.jpg" width="150" height="120"/>
      </td>
      <td>
         <img src="http://col.stb.s-msn.com/i/50/8CC964E5503A7F61F8AD22A12024.jpg" width="150" height="120"/>
      </td>
   </tr>
   <tr>
      <td>
         <img src="http://col.stb.s-msn.com/i/C4/F7EF634B7084DA69AAB5AAD05C8922.jpg" width="150" height="120"/>
      </td>
      <td>
         <img src="http://col.stb.s-msn.com/i/FB/C8367425D67FA391A5E0F8A3E0276B.jpg" width="150" height="120"/>
      </td>
   </tr>
</table>

Примечание :

  1. Использование оператора XPath mod для определения элементов каждой строки.

  2. Использование режимов для обработки одного и того же типа элемента (<pic>) двумя различными способами.

  3. Использование AVT (атрибут-значение-шаблоны), чтобы сделать код короче и более понятным.

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