2010-05-28 5 views
3

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

Входной 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> 
+0

Хороший вопрос (+1). См. Мой ответ для полного решения. –

ответ

7

Короткий ответ: вы с муравей.

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

Если имеется, то они могут быть выбраны как: '&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

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

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

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

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

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

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

0

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

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

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

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

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

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

Дополнительная информация на странице MSDN site.

Смежные вопросы