在XSLT中混淆空白问题

时间:2014-09-08 14:29:02

标签: xml xslt whitespace

我有两个版本的文档以一个TEI XML编码,并希望将其中一个版本输出到文本文件中。这是示例XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml"
schematypens="http://purl.oclc.org/dsdl/schematron"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
      <fileDesc>
         <titleStmt>
            <title>Title</title>
         </titleStmt>
         <publicationStmt>
            <p>Publication Information</p>
         </publicationStmt>
         <sourceDesc>
            <p>Information about the source</p>
         </sourceDesc>
      </fileDesc>
  </teiHeader>
  <text>
      <body>
         <p>John Q Doe was born in 
            <app>
               <rdg wit="text1">Omaha</rdg>
               <rdg wit="text2">Lincoln</rdg>
            </app>
        in 1950. But was he
            <app>
               <rdg wit="text1">happy</rdg>
               <rdg wit="text2">glad</rdg>
            </app>?
        Some say no.
         </p>
      </body>
  </text>
</TEI>

以下是示例XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs tei" version="2.0">

    <xsl:output omit-xml-declaration="yes" method="text" encoding="UTF-8"/>

    <xsl:template match="text()">
        <xsl:value-of select='normalize-space()'/>
    </xsl:template>


    <xsl:template match="/">
        <xsl:apply-templates></xsl:apply-templates>
    </xsl:template>

    <xsl:template match="tei:teiHeader">
    </xsl:template>

    <xsl:template match="tei:app">       
        <xsl:apply-templates/>
    </xsl:template>


    <xsl:template match="tei:rdg[@wit='text1']">
        <xsl:apply-templates/>
    </xsl:template>


    <!-- Cancel out the alternate version of the text-->
    <xsl:template match="tei:rdg[@wit='text2']">
    </xsl:template>

</xsl:stylesheet>

我想输出的是“John Q Doe于1950年出生在奥马哈。但他开心了吗?有人说没有。“我最终得到的是”John Q Doe出生于1950年的奥马海恩。但是他很高兴吗?有人说不。“所以,我不知何故需要在app元素周围保留一个空格。我不能preserve-space()因为我使用额外的空格来提高可读性,我不能简单地使用<xsl:text>tei:app的模板匹配上插入空格,因为有时标点符号会立即出现<app>元素,上面的问号也是如此。我很难过。

2 个答案:

答案 0 :(得分:1)

看起来你本质上想要一个normalize-space()的特殊情况,它只是将空格的运行(包括在字符串的开头和结尾处)归一化到一个空格,也没有剥离前导和尾随空格。由于您使用的是XSLT 2.0,因此可以使用简单的正则表达式执行此操作:

<xsl:template match="text()">
    <xsl:value-of select="replace(., '\s+', ' ')"/>
</xsl:template>

您还需要添加

<xsl:strip-space elements="*"/>

到样式表的顶部,以便压缩完全空格的文本节点。如果没有这个,您将在输出中为每个全空间文本节点添加额外空间(例如,在<text><body><body><p>之间, </rdg></app>等)。 strip-space指令仅影响所有空白文本节点,它不会影响也包含有用的非空间内容的文本节点中的空白。

答案 1 :(得分:0)

您需要添加缺少的空格。 如果您放置<xsl:text> </xsl:text>,您将在元素之前和之后获得空格:

<xsl:template match="tei:rdg[@wit='text1']">
    <xsl:text> </xsl:text>
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
</xsl:template>

这给出了以下输出:

John Q Doe was born in Omaha in 1950. But was he happy ? Some say no