XSLT 删除子节点并保留带有标点符号的空格
XSLT remove child nodes and keep whitespaces with punctuation
我有 XML 格式的 <mixed-citation>
文件,其中包括一些未标记的内容,如空格和标点符号:
<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>
转换模板实际上应该只解析所有标签,无论排除了哪些子标签,并始终保留所有预定义的空格和标点符号。如果它们意外出现,它应该只去除标签内的一些 leading/trailing 空格:即 <month> Jul </month>
到 <month>Jul</month>
.
另外,双倍输出是我的错误,我修正了上面的输出。
您可以将模板集压缩为以下内容:
<?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()
节点,它们不是 last()
并省略了所有 month
和 uri
元素,它们是 [=16= 的子元素].
mixed-citation/*/text() | mixed-citation/text()[last()]
模板规则省略了 mixed-citation
的所有 grand-children 或 mixed-citation
text()
节点的前导和尾随空格=].
结果如愿:
<!DOCTYPE HTML>
<html>
<p>
<p>Collab. Source. Location: Name; 2020. [comment].</p>
</p>
</html>
此解决方案不会使输出加倍。
如果这确实是您想要的而不是错误,则必须将 <xsl:template match="ref/mixed-citation">
模板中的 <p><xsl:apply-templates/></p>
加倍。
我有 XML 格式的 <mixed-citation>
文件,其中包括一些未标记的内容,如空格和标点符号:
<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>
转换模板实际上应该只解析所有标签,无论排除了哪些子标签,并始终保留所有预定义的空格和标点符号。如果它们意外出现,它应该只去除标签内的一些 leading/trailing 空格:即 <month> Jul </month>
到 <month>Jul</month>
.
另外,双倍输出是我的错误,我修正了上面的输出。
您可以将模板集压缩为以下内容:
<?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()
节点,它们不是 last()
并省略了所有 month
和 uri
元素,它们是 [=16= 的子元素].
mixed-citation/*/text() | mixed-citation/text()[last()]
模板规则省略了 mixed-citation
的所有 grand-children 或 mixed-citation
text()
节点的前导和尾随空格=].
结果如愿:
<!DOCTYPE HTML>
<html>
<p>
<p>Collab. Source. Location: Name; 2020. [comment].</p>
</p>
</html>
此解决方案不会使输出加倍。
如果这确实是您想要的而不是错误,则必须将 <xsl:template match="ref/mixed-citation">
模板中的 <p><xsl:apply-templates/></p>
加倍。