在保持缩进的同时删除换行符和双 space
Remove linebreak and double space while keeping indent
我希望保持缩进,而某些元素(xbrli:identifier、xbrli:startDate 和 xbrli:endDate)应该具有元素的 start/end 标记,并且它的值在同一行上(请参阅注释掉的数据:“想要的结构”。
如果它更简单、更有条理,我认为可以从没有断线和没有 start-/trailing space 开始。当然每句话之间的space要保持原样。
在之前的一些测试和场景中,我设法用“normalize-space()”解决了问题,但这要求代码以我拥有“xsl:value-of”的方式编写,当只执行“xsl:copy-of”时情况并非如此。
代码可在此处找到:
https://xsltfiddle.liberty-development.net/bET2rXp/1
下面是相同的代码:
数据:
<?xml version="1.0" encoding="utf-8" ?>
<xbrli:xbrl
xmlns:xbrli="http://www.example.com/1"
>
<!-- Start structure -->
<xbrli:context id="period0">
<xbrli:entity>
<xbrli:identifier scheme="http://www.example.se">
123 abc
</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
<xbrli:startDate>
2022-01-01
</xbrli:startDate>
<xbrli:endDate>
2022-12-31
</xbrli:endDate>
</xbrli:period>
</xbrli:context>
<!-- Wanted (result) structure -->
<!--
<xbrli:context id="period0">
<xbrli:entity>
<xbrli:identifier scheme="http://www.example.se">123 abc</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
<xbrli:startDate>2022-01-01</xbrli:startDate>
<xbrli:endDate>2022-12-31</xbrli:endDate>
</xbrli:period>
</xbrli:context>
-->
</xbrli:xbrl>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
xmlns:xbrli="http://www.example.com/1"
>
<!--<xsl:value-of select="normalize-space()"/>-->
<xsl:mode on-no-match="shallow-skip"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/xbrli:xbrl">
<xsl:copy-of select="//xbrli:xbrl/*">
</xsl:copy-of>
</xsl:template>
</xsl:stylesheet>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<xbrli:context xmlns:xbrli="http://www.example.com/1" id="period0">
<xbrli:entity>
<xbrli:identifier scheme="http://www.example.se">
123 abc
</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
<xbrli:startDate>
2022-01-01
</xbrli:startDate>
<xbrli:endDate>
2022-12-31
</xbrli:endDate>
</xbrli:period>
</xbrli:context>
如评论中所述,如果您需要更改数据,则需要为此设置一个模板,例如对所有非白色space 文本节点进行规范化 space:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[not(*) and normalize-space()]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:value-of select="normalize-space()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="comment()"/>
</xsl:stylesheet>
当然,模板只能匹配某些父元素的文本节点,如 xbrli:startDate
等,如果需要的话。
如果您真的很关心对序列化进行如此精细的控制,您可以考虑使用 fn:serialize()
对输出的不同部分进行序列化,对文档的不同部分使用不同的参数,然后组装这些部分.
我希望保持缩进,而某些元素(xbrli:identifier、xbrli:startDate 和 xbrli:endDate)应该具有元素的 start/end 标记,并且它的值在同一行上(请参阅注释掉的数据:“想要的结构”。
如果它更简单、更有条理,我认为可以从没有断线和没有 start-/trailing space 开始。当然每句话之间的space要保持原样。
在之前的一些测试和场景中,我设法用“normalize-space()”解决了问题,但这要求代码以我拥有“xsl:value-of”的方式编写,当只执行“xsl:copy-of”时情况并非如此。
代码可在此处找到: https://xsltfiddle.liberty-development.net/bET2rXp/1
下面是相同的代码:
数据:
<?xml version="1.0" encoding="utf-8" ?>
<xbrli:xbrl
xmlns:xbrli="http://www.example.com/1"
>
<!-- Start structure -->
<xbrli:context id="period0">
<xbrli:entity>
<xbrli:identifier scheme="http://www.example.se">
123 abc
</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
<xbrli:startDate>
2022-01-01
</xbrli:startDate>
<xbrli:endDate>
2022-12-31
</xbrli:endDate>
</xbrli:period>
</xbrli:context>
<!-- Wanted (result) structure -->
<!--
<xbrli:context id="period0">
<xbrli:entity>
<xbrli:identifier scheme="http://www.example.se">123 abc</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
<xbrli:startDate>2022-01-01</xbrli:startDate>
<xbrli:endDate>2022-12-31</xbrli:endDate>
</xbrli:period>
</xbrli:context>
-->
</xbrli:xbrl>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
xmlns:xbrli="http://www.example.com/1"
>
<!--<xsl:value-of select="normalize-space()"/>-->
<xsl:mode on-no-match="shallow-skip"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/xbrli:xbrl">
<xsl:copy-of select="//xbrli:xbrl/*">
</xsl:copy-of>
</xsl:template>
</xsl:stylesheet>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<xbrli:context xmlns:xbrli="http://www.example.com/1" id="period0">
<xbrli:entity>
<xbrli:identifier scheme="http://www.example.se">
123 abc
</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
<xbrli:startDate>
2022-01-01
</xbrli:startDate>
<xbrli:endDate>
2022-12-31
</xbrli:endDate>
</xbrli:period>
</xbrli:context>
如评论中所述,如果您需要更改数据,则需要为此设置一个模板,例如对所有非白色space 文本节点进行规范化 space:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[not(*) and normalize-space()]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:value-of select="normalize-space()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="comment()"/>
</xsl:stylesheet>
当然,模板只能匹配某些父元素的文本节点,如 xbrli:startDate
等,如果需要的话。
如果您真的很关心对序列化进行如此精细的控制,您可以考虑使用 fn:serialize()
对输出的不同部分进行序列化,对文档的不同部分使用不同的参数,然后组装这些部分.