Исправление отступа разделов CDATA - PullRequest
1 голос
/ 15 марта 2011

Я совершенно новичок в XML / XSL / XSLT, и пока я копал msdn, 3schools.com и Google в течение последнего часа, я не могу понять это. Я думаю, это потому, что CDATA не анализируется XML, но я подумал, что, так как мое редактирование действительно работает на узле, я должен быть в состоянии исправить это ...

Обратите внимание, что это не очень важная проблема, я просто хочу немного больше узнать о XSL и о том, что может быть лучше, чем исправление вещей, которые, кажется, не работают так, как я хочу.

Итак ... мой сценарий сохраняет параметры в XML-файле, в котором я также сохраню некоторые фрагменты кода, которые могут содержать символы, которые необходимо экранировать. Небольшой пример будет:

<Snippet title="Version Test">
<![CDATA[
version := "AHK Version: " a_ahkversion
unicode := "& Supports Unicode: " (a_isunicode ? "Yes" : "No")
Msgbox % version "`n" unicode
]]>
</Snippet>

Со следующим xsl я получаю довольно хороший отступ:

<!-- Extracted from: http://www.dpawson.co.uk/xsl/sect2/pretty.html (v2) -->
<!-- Cdata info: http://www.altova.com/forum/default.aspx?g=posts&t=1000002342 -->
<!-- Modified By RaptorX -->
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

<xsl:template match="*">
   <xsl:copy>
      <xsl:copy-of select="@*" />
      <xsl:apply-templates />
   </xsl:copy>
</xsl:template>

<xsl:template match="comment()|processing-instruction()">
   <xsl:copy />
</xsl:template>
</xsl:stylesheet>
<!-- I have to keep the indentation here in this file as 
i want it to be on the XML file -->

Ну, в принципе, он не соответствует разделам CDATA, так что, погуглив, я обнаружил, что могу сделать следующее, что немного помогает, но дает такой вывод:

xsl:copy-of select="@*|node()" /> << -- by adding that i match cdata nodes too

Output:
<Snippet title="Version Test">
   <![CDATA[
version := "AHK Version: " a_ahkversion
unicode := "Supports Unicode: " (a_isunicode ? "Yes" : "No")
Msgbox % version "`n" unicode
   ]]></Snippet>   <<-- here is the problem I cant seem to put a newline there lol

Итак, вопрос:

как мне сказать xsl сделать отступ для раздела CDATA, как это делается для всего остального:

    <root>
        <child/>
    </root>

   <Snippet title="Version Test">
   <![CDATA[
    version := "AHK Version: " a_ahkversion
    unicode := "Supports Unicode: " (a_isunicode ? "Yes" : "No")
    Msgbox % version "`n" unicode
   ]]> << --- this is what im looking for
   </Snippet>

Ответы [ 2 ]

2 голосов
/ 15 марта 2011

Это преобразование :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"
  cdata-section-elements="Snippet"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="Snippet/text()">
  <xsl:call-template name="replace"/>
  <xsl:text>&#xA;</xsl:text>
 </xsl:template>

 <xsl:template name="replace">
  <xsl:param name="pText" select="."/>

  <xsl:if test="string-length($pText) >0">
   <xsl:choose>
    <xsl:when test="not(contains($pText,'&#xA;'))">
     <xsl:value-of select="$pText"/>
    </xsl:when>

    <xsl:otherwise>
     <xsl:value-of select=
        "substring-before($pText, '&#xA;')"/>
     <xsl:text>&#xA;&#9;&#9;</xsl:text>

     <xsl:call-template name="replace">
      <xsl:with-param name="pText"
       select="substring-after($pText, '&#xA;')"/>
     </xsl:call-template>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML:

<Snippet title="Version Test">
<![CDATA[
version := "AHK Version: " a_ahkversion
unicode := "& Supports Unicode: " (a_isunicode ? "Yes" : "No")
Msgbox % version "`n" unicode]]>
</Snippet>

дает желаемый, правильный результат :

<Snippet title="Version Test"><![CDATA[

        version := "AHK Version: " a_ahkversion
        unicode := "& Supports Unicode: " (a_isunicode ? "Yes" : "No")
        Msgbox % version "`n" unicode

]]></Snippet>

Объяснение

  1. Правило идентификации копирует каждый узел "как есть".

  2. Атрибут cdata-section-elements="Snippet" <xsl:output> указывает процессору XSLT сериализовать любой текстовый узел любого элемента Snippet как раздел CDATA.

  3. Существует один шаблон, который переопределяет шаблон идентификации - при сопоставлении текстового узла, являющегося дочерним элементом элемента Snippet.

  4. Обработка любого такого текстового узла выполняется путем вызова шаблона replace, который заменяет любой символ NL на NL, за которым следуют два символа табуляции. Когда эти замены сделаны, выводится последний последний символ NL, так что конечный тег </Snippet> будет находиться на новой строке.

0 голосов
/ 15 марта 2011

Это глупо, но должно работать и очень быстро.Просто используйте <xsl:text>:

<xsl:copy />
<xsl:text>
</xsl:text>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...