我遇到了XSLT转换的问题。我输入XML如下:
<root>
<photoname>image</photoname>
<photocount>3</photocount>
</root>
我需要将其转换为以下XML:
<root>
<response>
<images>
<image>
<small>image_1_120.jpg</small>
</image>
</images>
<images>
<image>
<small>image_2_120.jpg</small>
</image>
</images>
<images>
<image>
<small>image_3_120.jpg</small>
</image>
</images>
</response>
</root>
是否可以使用XSLT(或使用XSLT中的C#函数)?
答案 0 :(得分:2)
这是一个非递归解决方案(您需要有足够的节点:)),也称为Piez method :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vCount" select="/*/photocount"/>
<xsl:template match="/*">
<root>
<response>
<xsl:for-each select=
"(document('')//node())[not(position() > $vCount)]">
<images>
<image>
<small>image_1_120.jpg</small>
</image>
</images>
</xsl:for-each>
</response>
</root>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档:
<root>
<photoname>image</photoname>
<photocount>3</photocount>
</root>
产生了想要的正确结果:
<root>
<response>
<images>
<image>
<small>image_1_120.jpg</small>
</image>
</images>
<images>
<image>
<small>image_1_120.jpg</small>
</image>
</images>
<images>
<image>
<small>image_1_120.jpg</small>
</image>
</images>
</response>
</root>
答案 1 :(得分:1)
您可以在XSLT中使用递归模板实现此功能,以根据 photocount 元素进行迭代
尝试以下XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<root>
<response>
<xsl:call-template name="photo">
<xsl:with-param name="name" select="photoname"/>
<xsl:with-param name="count" select="photocount"/>
</xsl:call-template>
</response>
</root>
</xsl:template>
<xsl:template name="photo">
<xsl:param name="name"/>
<xsl:param name="count"/>
<xsl:param name="current" select="1" />
<images>
<image>
<small>
<xsl:value-of select="concat($name, '_', $current, '_120.jpg')"/>
</small>
</image>
</images>
<xsl:if test="not($current >= $count)">
<xsl:call-template name="photo">
<xsl:with-param name="name" select="$name"/>
<xsl:with-param name="count" select="$count"/>
<xsl:with-param name="current" select="$current + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容:
<root>
<response>
<images>
<image>
<small>image_1_120.jpg</small>
</image>
</images>
<images>
<image>
<small>image_2_120.jpg</small>
</image>
</images>
<images>
<image>
<small>image_3_120.jpg</small>
</image>
</images>
</response>
</root>
请注意,我不知道如何生成 _120 后缀,所以我不得不在XSLT中对其进行硬编码。
答案 2 :(得分:1)
类似的东西:
<xsl:template match="photocount">
<xsl:call-template name="for.loop">
<xsl:with-param name="i">1</xsl:with-param>
<xsl:with-param name="count" select="." />
</xsl:call-template>
</xsl:template>
<xsl:template name="for.loop">
<xsl:param name="i" />
<xsl:param name="count" />
<xsl:if test="$i <= $count">
<images>
<image>
<small>image_<xsl:value-of select="$i"/>_120.jpg</small>
</image>
</images>
</xsl:if>
<xsl:if test="$i <= $count">
<xsl:call-template name="for.loop">
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="$count"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
答案 3 :(得分:1)
这个问题可能有很多方法。这是其中之一:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output indent="yes" />
<xsl:template match="root">
<xsl:element name="root">
<xsl:element name="response">
<xsl:call-template name="output">
<xsl:with-param name="name" select="photoname" />
<xsl:with-param name="value" select="photocount" />
</xsl:call-template>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template name="output">
<xsl:param name="name" />
<xsl:param name="value" as="xs:integer" />
<xsl:if test="$value > 1">
<xsl:call-template name="output">
<xsl:with-param name="name" select="$name" />
<xsl:with-param name="value" select="$value - 1" />
</xsl:call-template>
</xsl:if>
<xsl:element name="images">
<xsl:element name="image">
<xsl:element name="small">
<xsl:value-of select="concat($name, '_', $value, '_120.jpg')" />
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这是我的输出(在Altova XMLSpy下):
<?xml version="1.0" encoding="UTF-8"?>
<root>
<response>
<images>
<image>
<small>image_1_120.jpg</small>
</image>
</images>
<images>
<image>
<small>image_2_120.jpg</small>
</image>
</images>
<images>
<image>
<small>image_3_120.jpg</small>
</image>
</images>
</response>
</root>