Удалите разрыв строки и двойное пространство, сохраняя отступ

#xml #xslt #xslt-3.0

Вопрос:

Я хочу сохранить отступ, в то время как некоторые элементы (xbrli:идентификатор, xbrli:дата начала и xbrli:дата окончания) должны иметь начальный/конечный тег элемента и его значение в одной строке (см. Данные с комментариями:»Разыскиваемая структура».

Если это проще и структурированнее, я думаю, что можно было бы начать с отсутствия структурных линий и пробелов в начале/конце. Конечно, пространство между каждым предложением должно быть сохранено в неизменном виде.

В некоторых предыдущих тестах и сценариях мне удалось решить проблему с помощью «normalize-space ()», но для этого требуется, чтобы код был написан таким образом, чтобы у меня было «xsl:значение», чего не бывает при простом выполнении «xsl:копия».

Код можно найти здесь: 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>
 

Комментарии:

1. Ну, если входные элементы содержат данные с пробелом, и вы выполняете набор copy-of таких элементов, то, очевидно, вы получаете копию входных данных в результате с теми же данными, включая пробелы. Поэтому сделайте неглубокую копию узла элемента, обработайте дочерние узлы и напишите шаблон для текстовых узлов, который удаляет/нормализует пробелы, которые вам не нужны.

Ответ №1:

Как сказано в комментарии, если вам нужно изменить данные, вам необходимо настроить шаблон для этого, например, для всех текстовых узлов без пробелов, чтобы нормализовать пространство:

 <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 и т.д., Если это необходимо.

Ответ №2:

Если вы действительно заинтересованы в том, чтобы иметь такой точный контроль над сериализацией , вы могли бы рассмотреть возможность сериализации различных частей выходных fn:serialize() данных с использованием разных параметров для разных частей документа, а затем сборки деталей.