我有 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_download
的全局变量,其中我在for-each的每次迭代期间附加一个绝对路径字符串(使用函数f:download
并给它一个参数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>
我的所需输出是两个文件。
文件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>
请你知道如何使这项工作吗?
最好的,约翰尼
答案 0 :(得分:1)
在XSLT中,初始化后无法更改变量。相反,使用不同的模式处理XML节点两次,以便为文章元素生成不同的输出。也许以下内容足以完成您的任务:
<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>
答案 1 :(得分: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>
</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>
在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>
可以看出文件中包含了所需的结果。