如何从XML文件中获取<img src="?"/>标记的图像路径

时间:2010-08-08 15:08:25

标签: javascript html xslt

我想使用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 个答案:

答案 0 :(得分:3)

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>

在这里自己动手(将我的代码复制并粘贴到相应的框中):

答案 1 :(得分:2)

建议的输出中存在一个错误,因为<img/>元素必须在每个HTML版本中都有alt个属性。

无论如何,以下是这样做但没有那些可以通过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()仅使用路径的最后部分)并不是一个困难的扩展,假设说变换本身并不复杂。

编辑:

我自己和JohnB在这里进入更远的领域,以上就足以回答原来的问题了。

添加以更全面地回答JohnB的问题。以下是使用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>

答案 2 :(得分:1)

使用XSL。示例here。顺便问一下为什么你有no属性?

答案 3 :(得分:0)

这是一个遵循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(属性值模板)使代码更短,更容易理解。