Специальные символы XSLT - PullRequest
6 голосов
/ 28 мая 2010

В следующем преобразовании XSL как вывести символы '<' и '>'?

Входной XML:

<TestResult bugnumber="3214" testname="display.methods::close->test_ManyInvoke" errortype="Failure"><ErrorMessage><![CDATA[calling close() method failed - expected:<2>]]></ErrorMessage>

XSLT:

<xsl:template match="TestResult">
  <xsl:variable name="errorMessage">
   <xsl:value-of select="ErrorMessage" disable-output-escaping="yes"/>
  </xsl:variable>
  <Test name='{@testname}'>
   <TestResult>
    <Passed>false</Passed>
    <State>failure</State>
    <Metadata>
     <Entry name='bugnumber' value='{@bugnumber}' />
    </Metadata>
    <TestOutput>
     <Metadata>
      <Entry name='ErrorMessage' value='{$errorMessage}' />
     </Metadata>
    </TestOutput>
   </TestResult>
  </Test>
 </xsl:template>

Выходной XML:

<Test name="display.methods::close-&gttest_ManyInvoke"> 
 <TestResult>
  <Passed>false</Passed>
  <State>failure</State>
  <Metadata>
   <Entry name="bugnumber" value="3214"/>
  </Metadata>
  <TestOutput>
   <Metadata>
    <Entry name="ErrorMessage" value="calling close() method failed - expected:&lt;2&gt;"/>
   </Metadata>
  </TestOutput>
 </TestResult>
</Test>

Ответы [ 4 ]

9 голосов
/ 28 мая 2010

Краткий ответ : Вы не можете.

Длинный ответ : значение атрибутов не может содержать несколько специальных символов, таких как '<', '>' и '&'.

При наличии они экранируются как: '&lt;', '&gt;' и '&amp;'.

Эти символы могут быть получены, если в качестве метода вывода используется «текст», а это не ваш случай.

Также может отображаться текст, который выглядит как эти символы при отображении в браузере: используйте: '&lt;', '&gt;' и '&amp;'.

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

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

 <xsl:template match="/">
  <t> &lt; &amp; &gt;</t>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к любому документу XML (не используется), результат будет:

<t><![CDATA[ < & >]]></t>
1 голос
/ 20 мая 2016

Это действительно старый вопрос, и другие комментаторы, вероятно, правы, спрашивая, зачем вам это нужно, но если вы просто хотите узнать, как добавить <или> в ваш вывод, вот как вы это делаете.

<xsl:value-of disable-output-escaping="yes" select="string('&lt;')"/>

Больше информации на сайте MSDN .

1 голос
/ 28 мая 2010

Если факт, что &gt; отображается в ваших атрибутах, является проблемой, проблема заключается в том, как используется XML, а не как он создается.

Любой синтаксический анализатор XML будет удалять экранированные символьные объекты, когда он используется для получения значения атрибута. Если вы используете синтаксический анализатор XML при использовании XML-документа, вы никогда не увидите этого; парсер скажет вам, что значение атрибута display.methods::close->test_ManyInvoke.

Мне кажется, что эта "проблема" появляется только по одной из двух причин:

  1. Кто-то, кто не понимает, как работает XML, смотрит на вывод и говорит: «Эй, этого не следует делать».

  2. Кто-то, кто не понимает, как работает XML, написал свою собственную логику для анализа XML. («Зачем мне использовать чей-то синтаксический анализатор XML, когда я могу просто написать простое регулярное выражение?» Ну, это одна из причин, почему.)

Как правило, если вы когда-нибудь используете disable-output-escaping='yes' в XSLT или создаете разделы CDATA, вы, вероятно, делаете не то, что нужно. Это не определенно - есть подходящие варианты использования обоих, но, по моему опыту, в подавляющем большинстве случаев, если ответ «использовать CDATA», вы задаете неправильный вопрос.

0 голосов
/ 16 декабря 2015

Будьте осторожны, если вы пытаетесь избежать чего-либо, кроме амперсанда внутри строкового литерала. Например,

test="$some_variable = 'Wendy&apos;s'"

не будет работать. Вы должны экранировать первый амперсанд в escape-строке, поэтому вам нужно использовать

test="$some_variable = 'Wendy&amp;apos;s'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...