此XML包含要追加的字符串,字符串长度和要追加的字符的详细信息。
<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<input>
<string>Auckland</string>
<len>12</len>
<char>#</char>
</input>
<input>
<string>Ohio</string>
<len>3</len>
<char>*</char>
</input>
</data>
我还有一个XSLT应该(理想情况下)使用这个逻辑: while(字符串长度&lt;指定长度){ 连接(char,string) } 其他 {截断字符串到指定的长度}
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="append" match="/">
<xsl:param name="char"></xsl:param>
<xsl:param name="string"></xsl:param>
<xsl:param name="len"></xsl:param>
<xsl:value-of select="$string" />
<html>
<body>
<xsl:for-each select="data/input">
<xsl:choose>
<xsl:when test="string-length(string) < len" >
<xsl:call-template name="append">
<xsl:with-param name="char" select="char" />
<xsl:with-param name="string" select="concat(char,string)" />
<xsl:with-param name="len" select="len" />
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
由于某种原因,循环不能按预期工作。循环执行一次并显示结果。
例如,对于第一个XML输入,输出应该是#### Auckland,但结果是#Auckland。你能帮我识别一下这段代码中的缺陷吗?提前感谢您的帮助。
答案 0 :(得分:2)
这是一个简单,高效且非递归的XSLT 1.0解决方案:
<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="pFiller" select=
"'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$'"/>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="data/input"/>
</body>
</html>
</xsl:template>
<xsl:template match="input">
<div>
<xsl:value-of select=
"concat(string, substring(translate($pFiller,'$', char), 1, len))"/>
</div>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<data>
<input>
<string>Auckland</string>
<len>12</len>
<char>#</char>
</input>
<input>
<string>Ohio</string>
<len>3</len>
<char>*</char>
</input>
</data>
产生了想要的正确结果:
<html>
<body>
<div>Auckland############</div>
<div>Ohio***</div>
</body>
</html>
答案 1 :(得分:1)
我假设您正在指定使用XSLT 1.0;在2.0中,这将是一个微不足道的单线程。 但是,如果您愿意假设字符串的最大长度,我们仍然可以做一些简单的事情。
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="append" match="/">
<html>
<body>
<xsl:for-each select="data/input">
<xsl:value-of select="substring(concat(char,char,char,char,char,char,char,char,char,char,.), 10 + string-length() - len, len)"/>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
如果您对最大长度的假设不满意,您可以随时使用黑客:
<xsl:variable name="char" select="char"/>
<xsl:variable name="chars">
<xsl:for-each select="//*[position() <= $len]">
<xsl:value-of select="$char"/>
</xsl:for-each>
</xsl:variable>
除非len
大于输入文档中的节点数,否则其中有效。那你就可以做到
<xsl:for-each select="data/input">
<xsl:value-of select="substring($chars,.), string-length(), len)"/>
</xsl:for-each>
自下而上,虽然在XSLT 1.0中经常出现递归技术,并且对于学习很有用,但在这种特殊情况下并不是必需的。
答案 2 :(得分:0)
当我尝试使用XSLT时,我没有得到任何文本输出,主要是因为在您的代码中,您的命名追加模板需要字符串和的参数len ,但您分别使用参数 field 和 length 调用它。此外,您的命名模板也会与顶级文档元素匹配,因此它会多次输出 html 。
尽管如此,拥有匹配的模板也是完美的,这也是一个命名模板。试试这个XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="data/input"/>
</body>
</html>
</xsl:template>
<xsl:template match="input" name="append">
<xsl:param name="char" select="char"/>
<xsl:param name="string" select="string"/>
<xsl:param name="length" select="number(len)"/>
<xsl:choose>
<xsl:when test="string-length($string) < $length">
<xsl:call-template name="append">
<xsl:with-param name="char" select="$char"/>
<xsl:with-param name="string" select="concat($char,$string)"/>
<xsl:with-param name="length" select="$length"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<div>
<xsl:value-of select="$string"/>
</div>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
应用于XML时,输出以下内容
<html>
<body>
<div>####Auckland</div>
<div>Ohio</div>
</body>
</html>
请注意参数的默认值的使用。第一次访问模板时,通过模板匹配,值将默认为相关元素的值。当您随后将其称为命名模板时,它将使用您将其作为参数传递的值。
编辑:如果超过所需长度的值,您是否希望截断值,只需用此行替换现有的<xsl:value-of select="$string"/>
:
<xsl:value-of select="substring($string, 1, $length)"/>