问题描述
我希望保持缩进,而某些元素(xbrli:identifier、xbrli:startDate 和 xbrli:endDate)应该具有元素的开始/结束标记,并且它的值在同一行(请参阅注释掉的数据:“想要的结构”。
如果它更容易和更有条理,我认为可以从没有隔断线和开始/尾随空格开始。当然每个句子之间的空格应该保持完整。
在之前的一些测试和场景中,我设法用“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>
解决方法
如评论中所述,如果您需要更改数据,则需要设置一个模板来这样做,例如,对于所有非空白文本节点来规范化空间:
<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()
序列化输出的不同部分,对文档的不同部分使用不同的参数,然后组装这些部分。