[编辑:改变标题以更好地概念化问题。]
属性@xml:space
的值可以是"default"
或"preserve"
。 XML指定了第二个意味着什么,但是第一个意味着应用程序。 (我认为我有正确的。)那么如果应用程序希望default
实现XSchema的collapse
怎么办? XSLT 1.0怎么能真正做到这一点?
我认为用于处理文本的内置模板,即
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
需要替换为类似伪代码的东西:
<xsl:choose>
<xsl:when test="../@xml:space='preserve'"
<xsl:value-of select="."/>
</xsl:when>
<xsl:otherwise>
if position(.)=1 then output LTRIM(value-of(.))
if position(.)=last() then output RTRIM(value-of(.))
if position(.)= 1 and last()=1 then output normalize-space(.)
</xsl:otherwise>
</xsl:choose>
然后输入:
<persName> The man is
<forename>Edward</forename>
<forename>George</forename>
<surname type="linked">Bulwer-Lytton</surname>, <roleName>Baron Lytton of
<placeName>Knebworth</placeName>
</roleName>
</persName>
将The man is Edward George Bulwer-Lytton, Baron Lytton of Knebworth
正确呈现,The man
之前的空格和Knebworth
修剪后Edward
和George
之间的空格会崩溃。 (这个例子来自TEI。)
[编辑:我在这里删除了一个错误且误导性的段落。]
需要为每个文本节点执行实现该伪代码的XSLT 1.0。难道不是那么丑陋和缓慢吗? [编辑:或许不是。我简化了伪代码。有快速修剪程序吗?选择真的那么慢吗?]
结论:如何在XSLT 1.0中实现XSchema的崩溃(仅使用嵌入浏览器的扩展)?
我希望我说的都是正确的。我希望代码很简单。我还没有看到它是怎么回事。 [编辑:改变xs:崩溃到XSchema崩溃。]
答案 0 :(得分:0)
这是你想要的东西......
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
Demonstration of collapsed white space.
=======================================
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="concat(normalize-space(.),' ')" />
</xsl:template>
</xsl:stylesheet>
这会产生输出......
Demonstration of collapsed white space.
=======================================
The man is Edward George Bulwer-Lytton , Baron Lytton of Knebworth
答案 1 :(得分:0)
您尚未正确理解xml:space
的定义。
它仅适用于仅空白文本节点。它不适用于包含在也具有非空白字符的文本节点中的空白字符(也称为“重要空白空间”)。
“另一方面,”重要的“白色空间应该是 保存在交付版本中是常见的,例如在诗歌中 和源代码“
因此,“修剪”文本节点的整个想法与xml:space
无关。
This resource 包含对xml:space
属性的易于理解的解释。
<强>更新强>:
答案中的OP改变了他的初始要求。现在他想要的只是(如果我对他的答案的理解是正确的话)删除所有仅具有相同父级的空白文本节点中的第一个(我也认为是最后一个)仅空白文本节点。
这很简单 - 只需将此模板添加到XSLT样式表:
<xsl:template match=
"text()[not(normalize-space())][position() = 1 or position() = last()]"/>
答案 2 :(得分:0)
好编辑。谢谢Dimitre。
我不相信我正在阅读这个规格错误,但我假设了一下;让我来解决一下我的例子(也许我应该留下它来了)。
<persName>
<forename>Edward</forename>
<forename>George</forename>
<surname type="linked">Bulwer-Lytton</surname>, <roleName>Baron Lytton of
<placeName>Knebworth</placeName>
</roleName>
</persName>
我希望默认处理是删除<forename>Edward</forename>
之前的仅空白文本节点,而不是<forename>Edward</forename>
之后的仅空白文本节点。
但是,我不清楚xml:space仅指包含或删除仅空白文本节点,例如xsl:strip-space。事实上,正如您所指出的,2.10白色空间处理使用诗歌和源代码作为例子。那些是空间在文本节点内的情况。 @xml:space标识应该如何处理该空间。它应该以应用程序的默认方式保存或处理吗?
我认为http://www.xmlplease.com/xml/xmlspace/在这方面是错误的。
答案 3 :(得分:0)
我在xml-dev检查过,结果证明我对@xml:space的含义和用途是正确的。
以下是用于规范混合内容元素中的空白的代码(这是说出我想要做的更好的方式):
<xsl:template priority=".7" match="text()[position()=1 and not((ancestor::node()/@xml:space)[position()=last()]='preserve')]">
<xsl:value-of select="normalize-space()"/>
<xsl:if test="normalize-space(substring(., string-length(.))) = ''">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
<xsl:template priority=".7" match="text()[position()=last() and not((ancestor::node()/@xml:space)[position()=last()]='preserve')]">
<xsl:if test="normalize-space(substring(., 1, 1)) = ''">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="normalize-space()"/>
</xsl:template>
<xsl:template priority=".8" match="text()[position()=1 and position()=last() and not((ancestor::node()/@xml:space)[position()=last()]='preserve')]" >
<xsl:value-of select="normalize-space(.)"/>
</xsl:template>
@xml:space
上的过滤允许preserve
覆盖。 test=
只是测试空白的一种方法。优先级解决了当节点是元素中唯一的文本节点时产生的冲突,从而解决了第一个和最后一个节点之间的冲突。
答案 4 :(得分:0)
以您之前的答案为基础......如果您的文件看起来像这样
<document>
<p>A paragraph of text with subtags (whitespace after; no whitespace only between): Lorem
<italic>Before/After</italic> dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim <italic>Before/After</italic>
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>A paragraph of text with subtags (whitespace between: Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod <italic>Before/After</italic>
<italic>Before/After</italic> incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, <italic>Before/After</italic> <italic>Before/After</italic> laboris nisi ut aliquip
ex ea commodo consequat. </p>
</document>
然后,斜体标签之间的位不会被规范化空间模板捕获,因为它们既不在块的开头也不在块的末尾。
据我所知,你必须添加第四个来检查打开和关闭空间(并保留它),然后将这些内容标准化。
<xsl:template priority=".7" match="text()[not(position()=1) and not(position()=last())
and not((ancestor::node()/@xml:space)[position()=last()]='preserve')]" >
<xsl:if test="normalize-space(substring(., 1, 1)) = ''">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="normalize-space()"/>
<xsl:if test="normalize-space(substring(., string-length(.), 1)) = ''">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>