2

次のようなXMLがあります。

<article>
   <title>Article 1 title</title>
   <text>Lorem ipsum...</text>
   <image>http://example.com/img_01.jpg</image>
</article>
<article>
   <title>Article 2 title</title>
   <text>Dolor sit amet...</text>
   <image>http://example.com/img_02.jpg</image>
</article>

画像への相対パスのみを表示する必要があり、絶対パスを別のファイルに書き込む必要があります。と呼びましょうimg_to_download.html

これが私のアイデアです。image_src_downloadfor-each の反復ごとに 1 つの絶対パス文字列を追加する (関数f:downloadを使用してパラメーターを指定する)という名前のグローバル変数が 1 つありますimage_src。次に、for-each が終了したら、変数の内容をimage_src_download別のファイルに入れますimg_to_download.html

私のXSLTは次のようになります。

    <xsl:output method="html" encoding="UTF-8"/>

        <xsl:variable name="image_src"/> <!-- this is for a single entry-->
        <xsl:variable name="image_src_download"/> <!-- this should carry all sources to images -->

<!-- This function should append new string to the existing one in variable image_src_download -->
        <xsl:function name="f:download">
            <xsl:param name="newLink"/>
            <xsl:variable name="image_src_download">
                <xsl:value-of select="concat($image_src_download, $newLink, '\n')"/>
            </xsl:variable>
        </xsl:function>

        <xsl:template match="/">
            <html>
                <head>
                    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
                    <title>All articles</title>
                </head>
                <body>
                    <xsl:for-each select="article">
                        <h1><xsl:value-of select="title"/></h1>
                        <p><xsl:value-of select="text"/></p>

                        <xsl:variable name="image_src">
                            <xsl:value-of select="image"/>
                        </xsl:variable>
                        <xsl:variable name="image_src_rel">
                            <xsl:value-of select="substring($image_src, 20)"/> <!-- Strips beggining of the absolute URL and leaves just relative path to the file -->
                        </xsl:variable>

                            <xsl:value-of select="f:download($image_src)"/> <!-- This should append absolute path string of the current article image to variable image_src_download -->
                            <p><img src="{$image_src_rel}" /></p>
                    </xsl:for-each>

                </body>
            </html>

            <!-- Generates new file where there are absolute paths to images on each line-->
            <xsl:result-document href="img_to_download.html" method="html">
                <html>
                    <head>
                        <title>IMG to download</title>
                    </head>
                    <body>
                        <xsl:value-of select="$image_src_download"/>
                    </body>
                </html>
            </xsl:result-document>
        </xsl:template>

私の望む出力は2つのファイルです。articles.html次のようなファイル:

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
      <title>All articles</title>
    </head>
    <body>
      <h1>Article 1 title</h1>
      <p>Lorem ipsum...</p>
      <p><img src="img_01.jpg"/></p>

      <h1>Article 2 title</h1>
      <p>Dolor sit amet...</p>
      <p><img src="img_02.jpg"/></p>
    </body>
</html>

img_to_download.html次のようなファイル:

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
      <title>IMG to download</title>
    </head>
    <body>
      <p>
        http://example.com/img_01.jpg<br/>
        http://example.com/img_02.jpg<br/>    
      </p>
    </body>
</html>

これを機能させる方法を教えてください。

頑張れ、ジョニー

4

2 に答える 2

1

これは非常に簡単です

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

 <xsl:template match="/">
     <xsl:result-document href="articles.html">
     <html>
       <head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
          <title>All articles</title>
        </head>
        <body>
         <xsl:apply-templates/>
        </body>
    </html>
     </xsl:result-document>

     <xsl:result-document href="img_to_download.html">
    <html>
       <head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
          <title>IMG to download</title>
        </head>
        <body>
          <p>
           <xsl:apply-templates mode="url"/>
          </p>
        </body>
    </html>
     </xsl:result-document>
 </xsl:template>

 <xsl:template match="title/text()">
  <h1><xsl:value-of select="."/></h1>
 </xsl:template>

 <xsl:template match="text/text()">
  <p><xsl:value-of select="."/></p>
 </xsl:template>

 <xsl:template match="image">
  <xsl:variable name="vSrc" select=
   "replace(., 'http://((.+/)*)(.+)', '$3')"/>
  <p><img src="{$vSrc}"/></p>
 </xsl:template>

 <xsl:template match="*[not(self::image)]/text()" mode="url"/>

 <xsl:template match="image/text()" mode="url">
  <xsl:text>&#xA;</xsl:text>
  <xsl:value-of select="."/><br/>
 </xsl:template>
</xsl:stylesheet>

この変換が提供されたXMLドキュメントに適用される場合:

<html>
    <article>
        <title>Article 1 title</title>
        <text>Lorem ipsum...</text>
        <image>http://example.com/img_01.jpg</image>
    </article>
    <article>
        <title>Article 2 title</title>
        <text>Dolor sit amet...</text>
        <image>http://example.com/img_02.jpg</image>
    </article>
</html>

次の2つのファイルが作成されますC:\Program Files\Java\jre6\bin

articles.html:

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>All articles</title>
   </head>
   <body>
      <h1>Article 1 title</h1>
      <p>Lorem ipsum...</p>
      <p><img src="img_01.jpg"></p>
      <h1>Article 2 title</h1>
      <p>Dolor sit amet...</p>
      <p><img src="img_02.jpg"></p>
   </body>
</html>

img_to_download.html:

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>IMG to download</title>
   </head>
   <body>
      <p>
         http://example.com/img_01.jpg<br>
         http://example.com/img_02.jpg<br></p>
   </body>
</html>

そして、ファイルには正確に必要な結果が含まれていることがわかります

于 2012-05-22T03:39:33.267 に答える
1

XSLT では、一度初期化した変数を変更することはできません。代わりに、記事要素に対して異なる出力を生成するために、異なるモードで XML ノードを 2 回処理します。おそらく、次のようなもので十分です。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html"/>

  <xsl:template match="/">
    <html>
      <head>...</head>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
    <xsl:result-document href="img_to_download.html" method="html">
      <html>
        <head>...</head>
        <body>
          <p>
            <xsl:apply-templates mode="extern"/>
          </p>
        </body>
      </html>
    </xsl:result-document>    
  </xsl:template>

  <xsl:template match="article">
    <h1><xsl:value-of select="title"/></h1>
    <p><xsl:value-of select="text"/></p>
    <p><img src="{tokenize(image, '/')[last()]}"/></p>
  </xsl:template>

  <xsl:template match="article" mode="extern">
    <img src="{image}"/>
    <br/>
  </xsl:template>

  <xsl:template match="text()" mode="#all"/>
</xsl:stylesheet>
于 2012-05-21T14:46:36.700 に答える