我使用我的软件创建XML(即我可以控制其结构)。我想使用此XML通过使用不同的XSLT转换文件生成不同的结果。如何在结果中生成不同的文本,具体取决于使用的XSLT?
更具体:
我的结果文件应包含“点”字符,即。即…
或三个点,i。即...
,取决于使用的XSLT。使用一个XSLT,我的XML将导致第一个,而另一个XSLT,相同的XML(!)将导致第二个。我需要编写XSLT,以便将XML转换为一次,一次转换为另一种。
我的第一个方法是替换输入的子字符串。针对这个主题存在各种其他问题,但到目前为止还不适合我的情况:
…
,然后在XSLT中使用replace()
- 但我使用的XSLT 1.0不包含这个不错的功能。…
,然后在XSLT中使用translate()
- 但这只能将一个字符转换为一个字符,而我需要将...
作为输出之一(即不止一个字符。)&dots;
)并让XSLT将它们扩展为不同的字符串 - 这样做的唯一方法我发现实体与任何其他字符串完全相同,因此找不到解决方案。我仍然希望我使用这种方法找不到一个简单易用的解决方案。在XSLT 1.0中实现类似replace()
的东西有很多费力的解决方案。在使用这些之前,我宁愿创建不同的XML: - /
我很惊讶我的问题似乎很难解决,并且感觉我忽略了一些简单的事情。
答案 0 :(得分:1)
XSLT,尤其是版本1.0,具有更粗略的焦点,并且比您想要的更简约。它适用于处理节点,子节点及其值,但其内置的字符串操作功能有限。如果您不准备使用扩展函数,那么这意味着您可能需要为某些事情编写自己的XSLT。
例如,假设您生成包含单字符elipses的XML。您的其中一个转换可以直接传递这些转换。你的另一个可能会使用这样的机制将它们转换成三个点:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="text()">
<xsl:call-template name="translate-elipsis">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="translate-elipsis">
<xsl:param name="text"/>
<xsl:choose>
<xsl:when test="contains($text,'…')">
<xsl:value-of select="substring-before($text,'…')"/>
<xsl:text>...</xsl:text>
<xsl:call-template name="translate-elipsis" select="substring-after($text,'…')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
转换没有更具体匹配的所有文本节点的内容;如果需要,您也可以使用它来转换属性值。我认为它肯定比单个函数调用更冗长,但并非离谱。您可以使用类似的模式来编写用于字符串替换的通用模板。
答案 1 :(得分:1)
正如你所说,你掌握了XML,似乎只有一种方法就是在它自己的元素中标记特定数据,例如
<p>This is a text with an <ellipsis/>.</p>
然后在样式表中你想拥有三个点你只需要一个模板
<xsl:template match="ellipsis">
<xsl:text>...</xsl:text>
</xsl:template>
其他样式表将输出字符
<xsl:template match="ellipsis">
<xsl:text>…</xsl:text>
</xsl:template>
除此之外,我同意所提出的建议和意见,现在Java平台上支持XSLT 2.0甚至3.0,没有人被迫在JRE中使用FOP和内置的XSLT 1.0处理器。
答案 2 :(得分:0)
我使用来自https://stackoverflow.com/a/12364925/1281485的一些建议解决了FOP的问题:
添加一些名称空间后,我可以访问replaceAll()
,它按预期工作:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xalan="http://xml.apache.org/xalan"
xmlns:str="xalan://java.lang.String">
以后:
<xsl:template match="text()">
<xsl:value-of select="str:replaceAll(str:new(.), '…', '...')"/>
</xsl:template>
如果我将来发现任何问题,我可能会更新我的答案。到目前为止,它似乎解决了我的任务。