简体   繁体   English

如何获取图像路径 <img src=“?”> 来自XML文件的标记

[英]How to get image path for <img src=“?”> tag from XML file

I'd like to use an xml file 我想使用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>

in an html table: 在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>

Whats the best way to do this? 什么是最好的方法呢?

XML: 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: 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>

Try it yourself here (copy and paste my code into the appropriate boxes): 在这里自己动手(将我的代码复制并粘贴到相应的框中):

There's a bug in the suggested output, as <img/> elements must have alt attributes in every version of HTML in which they are present. 建议的输出中存在一个错误,因为<img/>元素必须在每个HTML版本中都有alt属性。

Anyway the following does this but without those attributes that can be done from CSS instead (just to keep size down). 无论如何,以下是这样做但没有那些可以通过CSS完成的属性(只是为了保持尺寸缩小)。 Adding them back in if desired is trivial: 如果需要,将它们添加回来是微不足道的:

<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>

The above assumes you want the path from the file used directly, adding code to transform it in some way (say taking just the last part of the path using substring-after() ) isn't a difficult extension, assuming said transform isn't complicated itself. 上面假设您想​​要直接使用文件的路径,添加代码以某种方式对其进行转换(比如使用substring-after()仅使用路径的最后部分)并不是一个困难的扩展,假设所述转换是'n'这很复杂。

Edit: 编辑:

Myself and JohnB are going into further territory here, the above suffices to answer the original question. 我和JohnB在这里进入更远的地方,上面就足以回​​答原来的问题了。

Added to give a fuller answer to JohnB's question. 添加以更全面地回答JohnB的问题。 The following is the equivalent code using for-each instead of apply-templates. 以下是使用for-each而不是apply-templates的等效代码。 In theory both a sequential and a state-machine base implementation of an XSLT processor should deal with this identically, though you may find differences in practice (if you told me they were different with a given processor I'd bet a small amount on it being slightly faster with sequential processing and slightly slower with state-machine processing, but I'd only bet a very small amount). 从理论上讲,XSLT处理器的顺序和状态机基本实现都应该以相同的方式处理这个问题,尽管你可能会发现实际上存在差异(如果你告诉我它们与给定的处理器有所不同,我会在它上面少量投注顺序处理稍快一点,状态机处理稍慢,但我只打赌一小部分)。

Note that we can't reuse the default template for pic. 请注意,我们无法重用pic的默认模板。 On the plus-side, if we have a different default template for pic elsewhere (if this were part of a much more complicated stylesheet), we don't need to be clever to differentiate between them, which is the main time that I personally would lean toward for-each. 从好的方面来说,如果我们在其他地方有一个不同的默认模板(如果这是一个更复杂的样式表的一部分),我们不需要聪明地区分它们,这是我个人的主要时间会倾向于每个人。

<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>

Use XSL. 使用XSL。 Example here . 这里的例子。 Btw why do you have the no attribute there ? 顺便问一下你为什么no属性?

Here is a typical solution that adheres to the spirit of XSLT (no <xsl:for-each> ), as short as possible, and parameterized on the desired number of columns in the table. 这是一个典型的解决方案,它遵循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>

When this transformation is applied on the following XML document (based on the provided XML document, but with more pictures that are really colorful and interesting): 当此转换应用于以下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>

the wanted result is produced (see it also in a browser :) ) : 产生了想要的结果 (也在浏览器中看到它:)):

<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>

Do note : 请注意

  1. The use of the XPath mod operator to determine the items of each row. 使用XPath mod运算符来确定每行的项目。

  2. The use of modes to process the same type of element ( <pic> ) in two different ways. 使用模式以两种不同的方式处理相同类型的元素( <pic> )。

  3. The use of AVT (attribute-value-templates) to make the code shorter and more understandable. 使用AVT(属性值模板)使代码更短,更易理解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM