2013-11-20 3 views
4

У меня есть ряд выходных документов по приложению Java, что экспорт XML с HTML-тегами незаменяемым, например, какXSL преобразование для вложенных HTML-тегов

<b>some text</b> 

(я не могу изменить это поведение).

Приложения, которое использует этот вывод должны иметь все HTML-теги убежали в

&lt;b&gt;some text &lt;/b&gt; 

Я использую XSLT ниже, чтобы избежать тегов, но не удивительно, что не работает для вложенных HTML-тегов, например, где есть

<u><b>A string of html</b></u> 

После XSLT преобразования я получаю

&lt;u&gt;a string of html&lt;/u&gt; 

where nested <b> and </b> tags get removed altogether. 

Ищу достичь

&lt;u&gt;&lt;b&gt;A string of html&lt;/b&gt;&lt;/u&gt; 

Я уверен, что есть простой ответ на этот вопрос путем корректировки стоимости из выбора или шаблона, но я попробовал и обанкротилась

Любая помощь будет высоко ценится !

Образец документ с внедренными HTML-теги

<?xml version="1.0" encoding="UTF-8"?> 
<Main> 
<Text><u><b>A string of html</b></u></Text> 
</Main> 

Это XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="UTF-8"/> 
<xsl:strip-space elements="*" /> 

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

<xsl:template match="Text/*"> 
    <xsl:value-of select="concat('&lt;',name(),'&gt;',.,'&lt;/',name(),'&gt;')" /> 
</xsl:template> 

</xsl:stylesheet> 

Который производит

<?xml version="1.0" encoding="UTF-8"?> 
<Main> 
    <Text>&lt;u&gt;A string of html&lt;/u&gt;</Text> 
</Main> 

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

Может ли кто-нибудь помочь с настройкой xslt?

Спасибо :-)

+1

+1 для четкого и разумно структурированного вопроса. –

+1

Может ли любой из тегов, которые вы хотите «убежать», иметь атрибуты (например, 'link')? –

+0

Да, они могут, но это покрыто решением Тима C ниже. Спасибо, что ответили! – user3012857

ответ

4

Попробуйте изменить текущий Text/* шаблон для этого

<xsl:template match="Text//*"> 
    <xsl:value-of select="concat('&lt;',name(),'&gt;')" /> 
    <xsl:apply-templates /> 
    <xsl:value-of select="concat('&lt;/',name(),'&gt;')" /> 
</xsl:template> 

Таким образом, Text//* будет соответствовать любой потомок элемента Text элемента, а не только непосредственный ребенок. Затем вы выводите шаблоны открытия и закрытия отдельно, а между ними вы рекурсивно вызываете шаблон для обработки «вложенных» элементов.

При нанесении на ваш образец XML, следующий должен быть выведен

<Main> 
    <Text>&lt;u&gt;&lt;b&gt;A string of html&lt;/b&gt;&lt;/u&gt;</Text> 
</Main> 
+0

Спасибо Тим, ты звезда. Это так блестяще просто и хорошо, очевидно, когда вы знаете! Я забыл все о синтаксисе XPath. Счастливое кодирование :-) – user3012857

1

Поскольку вы заявляете в комментарии, что теги, которые вы пытаетесь «избежать» может иметь атрибуты, Tim C's solution недостаточно.То, что вы на самом деле нужно что-то больше, как это (так как вы говорите, теги в которых идет речь, HTML, я буду считать, что вам не нужно заботиться о пространствах имен):

<xsl:template match="Text//*"> 
    <xsl:value-of select="concat('&lt;',name())" /> 
    <xsl:apply-templates select="@*" mode="escape" /> 
    <xsl:text>&gt;</xsl:text> 
    <xsl:apply-templates /> 
    <xsl:value-of select="concat('&lt;/',name(),'&gt;')" /> 
</xsl:template> 

<xsl:template match="@*" mode="escape"> 
    <xsl:value-of select="concat(' ', name(), '=&quot;')" /> 
    <xsl:call-template name="doubleEscapeQuotes" /> 
    <xsl:text>"</xsl:text> 
</xsl:template> 

<xsl:template name="doubleEscapeQuotes"> 
    <xsl:param name="value" select="string(.)" /> 
    <xsl:choose> 
    <xsl:when test="contains($value, '&quot;')"> 
     <xsl:value-of select="substring-before($value, '&quot;')" /> 
     <xsl:text>&amp;quot;</xsl:text> 
     <xsl:call-template name="doubleEscapeQuotes"> 
     <xsl:with-param name="value" select="substring-after($value, '&quot;')" /> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$value" /> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

это будет конвертировать

<a title="An &quot;example&quot; website" href="http://example.com">link</a> 

в

&lt;a title="An &amp;quot;example&amp;quot; website" href="http://example.com"&gt;link&lt;/a&gt; 

, но она по-прежнему не хватает какой-то необходимой логики - вы должны дважды бежать по мере амперсанд (&amp;amp;) и менее чем (&amp;lt;) признаки, как вэй l, в значениях обоих атрибутов и в текстовом содержимом HTML-элементов, чтобы сохранить полученную разметку хорошо сформированной после того, как она становится незакрашенной (вам также может понадобиться избегать большего, чем знаки для удобочитаемости, но это не так важно как & и <).

Это гораздо сложнее, чем прежде. Могут быть полезны различные ответы на вопрос this question.

+0

Ian вы абсолютно правы, и спасибо за обновление, к счастью, я обнаружил, что ни один из html-тегов не будет иметь атрибутов, и да, вы снова правы, это намного сложнее, чем вначале взгляд. Хотел бы я принять оба ответа! – user3012857

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