正常化在混合内容元素的空白,在XSLT 1.0(Normalize whitespace in mi

2019-10-16 23:32发布

[编辑:更改标题,以更好地概念化的问题。]

该属性的值@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 manKnebworth修剪和之间的空间EdwardGeorge倒塌。 (该例子是从TEI)。

[编辑:我在这里删除了不正确的和误导性的段落。]

在XSLT 1.0实现一个伪代码就需要为每个文本节点执行。 那不是丑陋和缓慢? [编辑:或者,也许不是。 我简单的伪代码。 是否有快速修整程序? 是选择真的那么慢?]

底线:一个人如何实现XSchema在XSLT 1.0崩溃(只内嵌浏览器的扩展)?

我希望我正确说了这一切。 我希望的代码很简单。 我还没有看到,怎么会这样。 [编辑:改变XS:崩XSchema的崩溃。]

Answer 1:

下面是一些接近你想要什么?

<?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


Answer 2:

好编辑。 谢谢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:空间是指只包含或只有空白文本删除节点,如XSL:带状空间,例如,做。 事实上,2.10空白处理用途,你注意,诗歌和源代码作为例子。 这些都是情况下的空间是一个文本节点内部。 @xml:空间标识的空间应该如何处理。 它应该被保存或应用程序的默认方式处理?

我认为http://www.xmlplease.com/xml/xmlspace/是错误的这一点。



Answer 3:

您还没有正确认识的定义xml:space

它仅适用于只有空白文本节点 。 它并不适用于那些包含在也有非空白字符的文本节点空白字符(也称为“显著白色空间”)。

从XML 1.0规范

在另一方面,‘显著’应在交付版本中保存的空白是常见的,如在诗歌和源码

因此,“微调”文本节点的整体思路已经无关xml:space

此资源包含一个容易理解的解释xml:space属性。

更新

在回答中的OP已经改变了他最初的要求。 现在,所有他想要的是(如果我的回答他的理解是正确的)删除第一个(我也觉得过去的),在具有相同的父都只是空白文本节点只有空白文本节点。

这很简单-只是这个模板添加到XSLT样式表

<xsl:template match=
   "text()[not(normalize-space())][position() = 1 or position() = last()]"/>


Answer 4:

我在XML-dev的检查,而且事实证明我是对的正确含义和用途@xml:空格。

这里是代码正常化的混合内容元素的空白(这是一个更好的方式来告诉你我想要做的):

<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=只是用于测试的空白方式。 该优先解决导致冲突当一个节点是一个元素的纯文本节点,因此第一和最后一个。



Answer 5:

建立在你前面的回答......如果你有一个看起来像这样的文件

<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>


文章来源: Normalize whitespace in mixed-content elements, in XSLT 1.0
标签: xml xslt