我认为这很简单。这是我的意见。我对其布局没有任何控制权。
<?xml version="1.0" encoding="UTF-8"?>
<topic>
<title>The Torments of Hell</title>
<body>
<p>Life is a <xref href="dungeon.xml">dungeon
</xref> and
an <xref href="abyss.xml">abyss</xref>.
</p>
</body>
</topic>
我想要获得的输出:
...
Life is a<ref>[[dungeon|dungeon.xml]]</ref> and an <ref>[[abyss|abyss.xml]]</ref>.
...
所以WYSIWYG(不同工具的输出,我无法控制,并将ref
标签转换为带引号的脚注)将如下所示:
生命是地牢 1 和深渊 2 。
这是我开始使用的xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="topic">
<xsl:text>
=</xsl:text>
<xsl:value-of select="title"/>
<xsl:text>=</xsl:text>
<xsl:apply-templates select="body/p"/>
</xsl:template>
<xsl:template match="p">
<xsl:text>

</xsl:text>
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="xref">
<xsl:text disable-output-escaping="yes"><ref></xsl:text>
<xsl:text>[[</xsl:text>
<xsl:value-of select="."/>
<xsl:text>|</xsl:text>
<xsl:value-of select="@href"/>
<xsl:text>]]</xsl:text>
<xsl:text disable-output-escaping="yes"></ref></xsl:text>
</xsl:template>
</xsl:stylesheet>
这是我得到的输出:
...
Life is a <ref>[[dungeon|dungeon.xml]]</ref> and
an <ref>[[abyss|abyss.xml]]</ref>.
...
没问题,我只会使用normalize-space
来摆脱换行符:
<xsl:template match="text()">
<xsl:value-of select="normalize-space(.)"/>
</xsl:template>
现在我的输出如下:
...
Life is a<ref>[[dungeon|dungeon.xml]]</ref>and an<ref>[[abyss|abyss.xml]]</ref>.
...
我的WYSIWYG看起来像这样:
生命是adungeon 1 和anabyss 2 。
换行消失了,但ref
标签之前和之后的空格也是如此;这些我想保留。我可以破解它并在我的ref
标签之前和之后添加一个空格,但后来我觉得这个丑陋:
生命是地牢 1 和深渊 2 。
注意 abyss 和句点之间的空格。我尝试了解决方案here和here,但这些只消除了额外的空格;他们对换行没有帮助。
我花了一整天的时间尝试用XSL做这件事,没有运气。然后我花了45分钟写了一个完全符合我想要的javascript。实际的,直接的问题解决了,但对我来说,使用XSL这将是如此困难似乎很奇怪。看起来很简单。有没有办法用XSL做到这一点,还是我需要在应用样式表之前预处理XML?
答案 0 :(得分:1)
鉴于您使用的是XSLT 2.0版,您可以使用带有replace
函数的正则表达式来获取normalize-space()
行为的“空格直到单个空格”,而不会获得“并修剪前导和尾随空白”部分。
<xsl:template match="text()">
<xsl:value-of select="replace(., '\s+', ' ')"/>
</xsl:template>
这会将空格的前导和/或尾随运行压缩到单个空格(与任何内部空格的运行一样),但不会完全删除它们。
另外,您不需要对disable-output-escaping
标记使用ref
,因为它们在模板内部得到了适当的平衡。刚
<xsl:template match="xref">
<ref>
<xsl:text>[[</xsl:text>
<xsl:value-of select="."/><!-- or <apply-templates/> -->
<xsl:text>|</xsl:text>
<xsl:value-of select="@href"/>
<xsl:text>]]</xsl:text>
</ref>
</xsl:template>
会正常工作。
答案 1 :(得分:0)
你可以在没有normalize-space
功能的情况下使用模板匹配去掉换行符,这里有一个例子:
<xsl:template match="yourText">
<xsl:call-template name="replace">
<xsl:with-param name="string" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="replace">
<xsl:param name="string"/>
<xsl:choose>
<xsl:when test="contains($string, ' ')">
<xsl:value-of select="substring-before($string, ' ')"/>
<xsl:call-template name="replace">
<xsl:with-param name="string" select="substring-after($string, ' ')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
这将删除文字中newline
的所有出现。
编辑:然后您可以调用结果上的normalize-space
函数来删除多余的空格。