XSLT анализирует экранированный HTML, хранящийся в атрибуте, и преобразует содержимое этого атрибута в содержимое элемента. - PullRequest
3 голосов
/ 22 февраля 2010

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

У меня есть элемент XML с атрибутом, который содержит экранированные элементы HTML:

<Booking>    
  <BookingComments Type="RAM" comment="RAM name fred&lt;br/&gt;Tel 09876554&lt;br/&gt;Email fred@bla.com" />
</Booking>

Что мне нужно получить, так это проанализировать HTML-элементы и контент из атрибута @comment, чтобы они содержали элемент

следующим образом:

<p>
  RAM name fred<br/>Tel 09876554<br/>Email fred@bla.com
<p>

Вот мой XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="xs fn" version="1.0">


<xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" 
    doctype-system="http://www.w3.org/TR/html4/loose.dtd" encoding="UTF-8" indent="yes" />

 <xsl:template name="some-template">
   <p>Some text</p>
   <p>
      <xsl:copy-of
        select="/Booking/BookingComments[lower-case(@Type)='ram'][1]/@comment"/>
   </p>     
 </xsl:template>
</xsl:stylesheet>

Я читал, что copy-of - это хороший способ восстановить экранированные элементы HTML обратно в соответствующие элементы. В данном конкретном случае, поскольку изначально это атрибут, копия также переводит его в атрибут. Итак, я получаю:

<p comment="RAM name fred<br/&gt;Tel 09876554<br/&gt;Email fred@bla.com"></p>

Чего я не хочу.

Если я использую apply-templates вместо copy-of, как в:

<p>
  <xsl:apply-templates select="/Booking/BookingComments[lower-case(@Type)='ram'[1]/@comment"/>
</p>

Я получаю содержимое p просто как текст, а не восстановленные элементы HTML.

<p>RAM name fred&lt;br/&gt;Tel 09876554&lt;br/&gt;Email fred@bla.com</p>

Уверен, я что-то упустил. Буду очень признателен за любую помощь и советы!

Ответы [ 2 ]

4 голосов
/ 22 февраля 2010

Я бы рекомендовал использовать специальный шаблон:

<!-- check if lower-casing @Type is really necessary -->
<xsl:template name="BookingComments[lower-case(@Type)='ram']/@comment">
  <p>
    <xsl:value-of select="." disable-output-escaping="yes" />
  </p>     
</xsl:template>

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

0 голосов
/ 22 февраля 2010

Вы можете связать функцию расширения parse (), которая анализирует строку в наборе узлов. Точный механизм зависит от вашего движка XSLT.

В Xalan мы можем использовать следующий статический метод:

public class MyExtension
{
    public static NodeIterator Parse( string xml );
}

и используйте его так:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:java="http://xml.apache.org/xalan/java"
    exclude-result-prefixes="java"
    version="1.0">

    <xsl:template match="BookingComments">
        <xsl:copy-of select="java:package.name.MyExtension.Parse(string(@comment))" />
    </xsl:template>

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