Как я могу использовать Escaped XML представление узла в выводе моего XSLT HTML - PullRequest
2 голосов
/ 14 апреля 2010

Я преобразую XML в документ HTML. В этом документе я хочу встроить разметку XML для только что преобразованного узла (документ HTML представляет собой техническую спецификацию).

Например, если мой XML был таким:

<transform-me>
    <node id="1">
        <stuff type="floatsam">
           <details>Various bits</details>
        </stuff>
    </node>
</transform-me>

Я бы хотел, чтобы мой вывод XSLT выглядел примерно так:

<h1>Node 1</h1>
   <h2>Stuff (floatsam)</h2>
   Various bits
   <h2>The XML</h2>
   &lt;stuff type=&quot;floatsam&quot;&gt;
      &lt;details&gt;Various bits&lt;/details&gt;
   &lt;/stuff&gt;

Я надеюсь, что есть функция XSLT, которую я могу вызвать в своем шаблоне , в которую я могу передать текущий узел (.) И вернуть экранированную разметку XML для и всех его потомков. У меня такое чувство, что unparsed-text () может быть правильным, но я не могу заставить его работать.

Ответы [ 2 ]

8 голосов
/ 16 апреля 2010

Очень простой шаблон

<xsl:template match="node()" mode="print">

        <xsl:choose>

            <!-- is it element? -->
            <xsl:when test="name()">

                <!-- start tag -->
                <xsl:text>&lt;</xsl:text>
                <xsl:value-of select="name()" />

                <!-- attributes -->
                <xsl:apply-templates select="@*" mode="print" />

                <xsl:choose>

                    <!-- has children -->
                    <xsl:when test="node()">
                        <!-- closing bracket -->
                        <xsl:text>&gt;</xsl:text>

                        <!-- children -->
                        <xsl:apply-templates mode="print" />

                        <!-- end tag -->
                        <xsl:text>&lt;/</xsl:text>
                        <xsl:value-of select="name()" />
                        <xsl:text>&gt;</xsl:text>
                    </xsl:when>

                    <!-- is empty -->
                    <xsl:otherwise>
                        <!-- closing bracket -->
                        <xsl:text>/&gt;</xsl:text>
                    </xsl:otherwise>

                </xsl:choose>

            </xsl:when>

            <!-- text -->
            <xsl:otherwise>
                <xsl:copy />
            </xsl:otherwise>

        </xsl:choose>

</xsl:template>

<xsl:template match="@*" mode="print">
    <xsl:text> </xsl:text>
    <xsl:value-of select="name()" />
    <xsl:text>=&quot;</xsl:text>
    <xsl:value-of select="." />
    <xsl:text>&quot;</xsl:text>
</xsl:template>

б

<xsl:apply-templates mode="print" />

Вы даже можете добавить красивую печать, если хотите.

7 голосов
/ 16 апреля 2010

Ответ на этот вопрос более сложный, чем вы могли подумать. Должно произойти правильное «двойное экранирование» значений атрибутов и текстовых узлов.

Этот шаблон XSLT 1.0 выполняет правильную (хотя и не полную) печать узла XML, включая (попытку сделать) правильную красивую печать с настраиваемым отступом:

<code><xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:output method="html" encoding="utf-8" />

   <!-- defaults and configurable parameters -->
  <xsl:param name="NL"        select="'&#xA;'" /><!-- newline sequence -->
  <xsl:param name="INDENTSEQ" select="'&#x9;'" /><!-- indent sequence -->

  <xsl:variable name="LT" select="'&lt;'" />
  <xsl:variable name="GT" select="'&gt;'" />

  <xsl:template match="transform-me">
    <html>
      <body>
        <!-- this XML-escapes an entire sub-structure -->
        <pre><xsl:apply-templates select="*" mode="XmlEscape" />
</ XSL: шаблон> <! - здесь будут обрабатываться узлы элементов, в т.ч. правильный отступ -> </ XSL: если> <! - рендерить дочерние узлы -> </ XSL: Наносить-шаблоны> </ XSL: если> </ XSL: когда> </ XSL: в противном случае> </ XSL: выберите> </ XSL: шаблон> <! - комментарии будут обрабатываться здесь -> </ XSL: шаблон> <! - текстовые узлы будут напечатаны XML-экранированными -> </ XSL: вызов-шаблон> </ XSL: если> </ XSL: шаблон> <! - атрибуты становятся строкой: '{name ()} = "{escaped-value ()}"' -> </ XSL: вызов-шаблон> </ XSL: шаблон> <! - шаблон для XML-экранирования строки -> <! - символы &, <и> никогда не допускаются -> </ XSL: вызов-шаблон> </ XSL: переменная> </ XSL: вызов-шаблон> </ XSL: переменная> </ XSL: вызов-шаблон> </ XSL: переменная> <! - chars ", TAB, CR и LF никогда не допускаются в атрибутах -> </ XSL: вызов-шаблон> </ XSL: переменная> </ XSL: вызов-шаблон> </ XSL: переменная> </ XSL: вызов-шаблон> </ XSL: переменная> </ XSL: вызов-шаблон> </ XSL: переменная> </ XSL: когда> </ XSL: в противном случае> </ XSL: выберите> </ XSL: шаблон> <! - шаблон замены общей строки -> </ XSL: вызов-шаблон> </ XSL: если> </ XSL: когда> </ XSL: в противном случае> </ XSL: выберите> </ XSL: шаблон> </ XSL: таблицы стилей>

Применительно к этому тесту XML:

<transform-me>
  <node id="1">
    <!-- a comment -->
      <stuff type="fl&quot;&apos;&#10;&#9;oatsam">
        <details>Various bits &amp; pieces</details>
        <details>
        </details>
        <details attr="value">
          <childnode>text and &lt;escaped-text /&gt;</childnode>
        </details>
      </stuff>
  </node>
</transform-me>

Производится следующий вывод (исходный код):

<code><html>
<body>
<pre>&lt;node id="1"&gt;
    &lt;!-- a comment --&gt;
    &lt;stuff type="fl&amp;quot;'&amp;#xD;&amp;#x9;oatsam"&gt;
        &lt;details&gt;Various bits &amp;amp; pieces&lt;/details&gt;
        &lt;details /&gt;
        &lt;details attr="value"&gt;
            &lt;childnode&gt;text and &amp;lt;escaped-text /&amp;lt;&lt;/childnode&gt;
        &lt;/details&gt;
    &lt;/stuff&gt;
&lt;/node&gt;

и при просмотре в браузере вы видите:

<node id="1">
    <!-- a comment -->
    <stuff type="fl&quot;'&#xD;&#x9;oatsam">
        <details>Various bits &amp; pieces</details>
        <details />
        <details attr="value">
            <childnode>text and &lt;escaped-text /&lt;</childnode>
        </details>
    </stuff>
</node>

Обратите внимание, что под "не завершенным" я подразумеваю, что такие вещи, как пространства имен и инструкции обработки, например, в настоящее время не обрабатываются. Но для них легко сделать шаблон.

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