Toolbox
Toolbox

Reputation: 2493

Remove linebreak and double space while keeping indent

I am looking to keep indent, while some elements (xbrli:identifier, xbrli:startDate and xbrli:endDate) should have start/end tag of element and it's value on same line (see commented-out Data:"Wanted structure".

If it is easier and more structured I think one could start with having no breaklines and no start-/trailing spaces. Of course the space in between each sentence should be kept intact.

In some previous tests and scenarios I managed to solve the issue with "normalize-space()" but that requires that the code is written in a way that I have "xsl:value-of", which is not the case when just performing a "xsl:copy-of".

The code is found here: https://xsltfiddle.liberty-development.net/bET2rXp/1

Below you find the same code:

Data:

<?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>

Result:

<?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>

Upvotes: 0

Views: 47

Answers (2)

Michael Kay
Michael Kay

Reputation: 163322

If you're really concerned to have such fine control over serialization, you could consider serialising different parts of the output using fn:serialize(), with different parameters for different parts of the document, and then assembling the parts.

Upvotes: 1

Martin Honnen
Martin Honnen

Reputation: 167571

As said in a comment, if you need to change data you need to set up a template doing so, for instance for all non-whitespace text nodes to normalize 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>

Of course the template could only match text nodes of certain parent elements like xbrli:startDate etc. if needed instead.

Upvotes: 1

Related Questions