Как предотвратить перенос строки с помощью XSLT? - PullRequest
4 голосов
/ 15 июля 2010

У меня есть такой XML-код:

<root>
   <do-not-sort>
      <z/>
      <y/>
   </do-not-sort>
   <sortable>
      <e f="fog" h="bat" j="cat">
          <n n="p"/>
          <m n="p"/>
      </e>
      <d b="fop" c="bar" k="cab">
          <m o="p"/>
          <m n="p"/>
      </d>
   </sortable>
</root>

Я хочу отсортировать дочерние элементы "сортируемого" элемента по их текстовому представлению, чтобы получить следующее:

<root>
   <do-not-sort>
      <z/>
      <y/>
   </do-not-sort>
   <sortable>
      <d b="fop" c="bar" k="cab">
          <m n="p"/>
          <m o="p"/>
      </d>
      <e f="fog" h="bat" j="cat">
          <m n="p"/>
          <n n="p"/>
      </e>
   </sortable>
</root>

В настоящее время я делаю это, применяя следующий шаблон XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes" encoding="UTF-8" />

  <xsl:template match="@* | /">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="normalize-space(text()[1])" />
      <xsl:apply-templates select="*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="sortable//*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="normalize-space(text()[1])" />
      <xsl:apply-templates select="*">
        <xsl:sort data-type="text" select="local-name()" />
        <xsl:sort data-type="text" select="@*" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Сортировка работает правильно, но если отсортированные элементы имеют много атрибутов, каждый последующий атрибут переносится на новую строку, например:

<sortable>
    <this is="an" element="with" a="lot" of="attributes"
            and="the"
            excess="ones"
            each="wrap"
            onto="their"
            own="line"/>

Как мне сохранить все эти атрибуты в одной строке, т. Е.

<sortable>
    <this is="an" element="with" a="lot" of="attributes" and="the" excess="ones" each="wrap" onto="their" own="line"/>

1 Ответ

4 голосов
/ 15 июля 2010

Как сохранить все эти атрибуты в одной строке

В вашем коде замените :

  <xsl:output method="xml" indent="yes" encoding="UTF-8" /> 

с

  <xsl:output method="xml" encoding="UTF-8" /> 

Конечно, это даст полный вывод в одной строке!На момент написания этой XSLT 2.0 до сих пор не было более детального контроля над сериализацией вывода.

Если вам нужны некоторые элементы с отступом, а некоторые нет, то вам придется предоставить свой собственный пост.-обработка (и эту постобработку проще написать с чем-то отличным от XSLT).

Обновление :

На самом деле, с использованием Saxon 9.1.07 и

  <xsl:output method="html" encoding="UTF-8" />

, где полное преобразование:

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="html" encoding="UTF-8" />

  <xsl:template match="@* | /">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="normalize-space(text()[1])" />
      <xsl:apply-templates select="*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="sortable//*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="normalize-space(text()[1])" />
      <xsl:apply-templates select="*">
        <xsl:sort data-type="text" select="local-name()" />
        <xsl:sort data-type="text" select="@*" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

и исходный XML-документ:

<root>
   <do-not-sort>
      <z></z>
      <y></y>
   </do-not-sort>
   <sortable>
      <this is="an" element="with" a="lot" of="attributes" and="the" excess="ones" each="wrap" onto="their" own="line"></this>
      <e f="fog" h="bat" j="cat"></e>
      <d b="fop" c="bar" k="cab"></d>
      <d b="foo" c="baz" k="cap"></d>
   </sortable>
</root>

Я получаю вывод с требуемым отступом:

<root>
   <do-not-sort>
      <z></z>
      <y></y>
   </do-not-sort>
   <sortable>
      <this is="an" element="with" a="lot" of="attributes" and="the" excess="ones" each="wrap" onto="their" own="line"></this>
      <e f="fog" h="bat" j="cat"></e>
      <d b="fop" c="bar" k="cab"></d>
      <d b="foo" c="baz" k="cap"></d>
   </sortable>
</root>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...