XSLT删除子节点并使用标点符号保留空格

时间:2020-09-20 21:35:58

标签: xml xslt xslt-2.0

我有一个<mixed-citation>格式的XML文件,其中包含一些未标记的内容,例如空格和标点符号:

<ref>
    <mixed-citation publication-type="book">
        <collab>Collab</collab>. <source>Source</source>. <publisher-loc>Location</publisher-loc>: <publisher-name>Name</publisher-name>; <month>Jul</month> <year>2020</year>. [comment].
        <uri xlink:href="https://www.google.com" xmlns:xlink="http://www.w3.org/1999/xlink">URL</uri>
    </mixed-citation>
</ref>

到目前为止,我设法构建了这个半功能的XSLT,它复制了所有节点值,保留了空格和标点符号,还删除了两个子节点“ month”和“ uri”:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    
    <xsl:output method="html" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:mode on-no-match="shallow-skip"/>
    
    <xsl:template match="ref">
        <html>
            <p>
                <xsl:apply-templates/>
            </p>
        </html>
    </xsl:template>
    
    <xsl:template match="ref/mixed-citation">
        <p>
            <xsl:apply-templates/>
        </p>
    </xsl:template>
    
    <xsl:template match="ref//text()">
        <xsl:value-of select='normalize-space()'/>
    </xsl:template>
    
    <xsl:template match="ref//month">
    </xsl:template>
    
    <xsl:template match="ref//uri">
    </xsl:template>
    
</xsl:stylesheet>

我想创建一个简单的输出HTML文件,如下所示:

<html>
   <p>
      <p>Collab. Source. Location: Name; 2020. [comment].</p>
   </p>
</html

但是使用提供的XSLT文件,我得到这样的错误输出:

<html>
   <p>
      <p>Collab.Source.Location:Name;2020. [comment].</p>
   </p>
</html>

我在做什么错?也许不使用身份转换就可以有另一种方法吗?

更新:

使用@ zx485下面提供的解决方案,只有同时排除<month><uri>时,输出才正确。如果我仍然把它们留在那里,那么输出是错误的:

<p>Collab. Source. Location: Name; Jul2020. [comment].URL</p>

应该是:

<p>Collab. Source. Location: Name; Jul 2020. [comment]. URL</p>

转换模板实际上应该只解析所有标签,而不管排除哪个子元素,并始终保留所有预定义的空格和标点符号。如果标签意外出现,它应该只删除标签中的一些前导/后缀空格:即<month> Jul </month><month>Jul</month>

另外,输出翻倍是我的错误,我在上面固定了输出。

1 个答案:

答案 0 :(得分:1)

您可以将模板集压缩为以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    
    <xsl:output method="html" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:mode on-no-match="shallow-skip"/>
    
    <xsl:template match="ref">
        <html>
            <p>
                <xsl:apply-templates/>
            </p>
        </html>
    </xsl:template>
    
    <xsl:template match="ref/mixed-citation">
        <p>
            <xsl:apply-templates/>
        </p>
    </xsl:template>
    
    <xsl:template match="mixed-citation/*/text() | mixed-citation/text()[last()]">
        <xsl:value-of select='normalize-space(.)'/>
    </xsl:template>

    <xsl:template match="mixed-citation/text()[position() != last()]">
        <xsl:value-of select='.'/>
    </xsl:template>    

    <xsl:template match="ref//(month|uri)" />
    
</xsl:stylesheet>

以上模板集复制了所有非text()的{​​{1}}节点,并省略了last()的子元素的所有monthuri元素。

ref模板规则忽略了mixed-citation/*/text() | mixed-citation/text()[last()]mixed-citation的{​​{1}} last()节点的所有孙子元素的前导和尾随空格。 / p>

结果如预期:

text()

此解决方案不会使输出翻倍。
如果这确实是您想要的而不是错误,则必须将mixed-citation模板中的<!DOCTYPE HTML> <html> <p> <p>Collab. Source. Location: Name; 2020. [comment].</p> </p> </html> 加倍。

相关问题