Убедить Firefox проанализировать HTML, встроенный в XML (после применения XSL) - PullRequest
1 голос
/ 17 июля 2010

У меня есть несколько XML-файлов этой формы:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="biomirror.xsl"?>
<Thread>
    <Title> Some thread title </Title>
    <Posts>
        <Post>
            <Author> Me </Author>
            <Body>
                This is the post body, which <b>may</b> have embedded XHTML, including all sorts of things like:<br />
                <div class="quote">Quotes</div>
                I know it's XHTML, though, the program spitting out XML verifies that.
            </Body>
        </Post>
    </Posts>
</Thread>

Мне нужно отформатировать их в читаемые темы, поэтому я использую таблицу стилей CSS и таблицу стилей XSL. CSS работает, я точно знаю, что в этом нет ничего плохого. Моя проблема, похоже, связана с XSL, так как любой встроенный XHTML не анализируется Firefox. В IE это работает отлично и выходит с правильным форматированием, но в Firefox это полностью простой текст. Я предполагаю, что это связано с выходом из него перед выводом, но я не могу понять, как это предотвратить.

XSL - это:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output 
  omit-xml-declaration="yes" 
  method="xml" 
  media-type="application/xhtml+xml" 
  indent="no" 
  doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
/>
<xsl:template match="Posts">
<xsl:for-each select="Post">
    <tr xmlns="http://www.w3.org/1999/xhtml" class="Post">
      <td>
        <div>
          <table width="100%" cellpadding="0" cellspacing="0">
            <tr>
              <td class="Author">
                <xsl:value-of select="Author"/>
              </td>
              <td class="Date">
                Post <xsl:value-of select="PostID"/> 
                <xsl:choose>
                  <xsl:when test="count(LastPost) > 0">
                    (lastpost)
                  </xsl:when>
                </xsl:choose> at <xsl:value-of select="Date"/>
              </td>
            </tr>
          </table>
        </div>
        <div class="Body">
           <xsl:copy-of select="Body" />
        </div>
        <xsl:choose>
          <xsl:when test="count(Sig) = 1">
            <div class="Sig">
              <xsl:value-of disable-output-escaping="yes" select="Sig"/>
            </div>
          </xsl:when>
          <xsl:when test="count(Sig) = 0">
            <div class="SigFooter"> </div>
          </xsl:when>
        </xsl:choose>
      </td>
    </tr>
</xsl:for-each>
</xsl:template>

<xsl:template match="Thread">
  <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <xsl:choose>
          <xsl:when test="count(Title) = 1">
            <title>
              <xsl:value-of select="Title"/>
            </title>
          </xsl:when>
        </xsl:choose>
        <link href="resources/main.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
      <table class="Thread" align="center" width="90%" height="95%" cellpadding="2em">
        <tr>
          <td colspan="3">
            <div class="Title">
          <xsl:value-of select="Title"/>
              <br />
              <a href="whatis.xml">
                <img src="resources/banner.png" />
              </a>
            </div>
          </td>
        </tr>
        <xsl:apply-templates select="Posts"/>
        <tr height="100%">
         <td valign="bottom">
       <div class="Footer">
             Footer message n stuff
           </div>
         </td>
        </tr>
      </table>
    </body>
  </html>
</xsl:template>

Это что-то вроде хака и любых странных атрибутов, которые я виню в Visual Studio. Это мой первый раз, когда я возился с XSL (хотя и относительно хорошо знаком с XML), поэтому я не представляю, что делать, чтобы это исправить. :)

Теперь я прочитал этот вопрос: XSLT: анализ HTML, встроенного в XML? и попытался интегрировать это в мой XML и XSL (как показано выше). Тем не менее, по-прежнему не работает в Firefox.

Редактировать: Кроме того, я попытался использовать xsl: value-of и xsl: copy-of для вывода содержимого. Значение выводит обычный текст и учитывает мое форматирование (из CSS), копирование выводит простой текст и разрушает мое форматирование (возвращается к форматированию тела, игнорируя div и таблицу).

Edit2: Пересмотрен XSL, чтобы отразить предложения из ответов. Форматирование в порядке, но встроенные теги по-прежнему выводятся в виде текста и не интерпретируются.

Ответы [ 3 ]

1 голос
/ 17 июля 2010

Первое: я запускаю это с Firefox 3.5.9.У него нет проблем, но это неправильно.

Когда вы говорите:

<xsl:copy-of select="child::Body" /> 

Вы копируете элемент не пространства имен с его содержимым.И поскольку вы не объявили это содержимое с пространством имен XHTML, это не элементы XHTML.Они должны иметь декларацию xmlns="".Но моя версия Firefox делает что-то неправильно: не интерпретировать ни один элемент пространства имен (как пример b) как элементы XHTML (без пустого пространства имен!).Поскольку вы не предоставили таблицу стилей CSS, я не могу выполнить тест CSS (если элементы пространства имен не получают стиль).

Редактировать : MSXSL правильно добавляет xmlns="" объявление в Body, но тогда IE рендерит все, что хочет MS.JA!

1 голос
/ 17 июля 2010

Во-первых, вам не нужны эти объявления:

xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"

их безопасно удалить.

Во-вторых, вам никогда не нужно упоминать ось child::.Это неявно в XSLT, просто выкините его без замены.

В-третьих, переместите объявление пространства имен XHTML

xmlns="http://www.w3.org/1999/xhtml"

в элемент <xsl:stylesheet> и удалите его повсюду.

И последнее, но не менее важное: пробовали ли вы правильный метод вывода и тип носителя для XHTML?

<xsl:output method="xml" media-type="application/xhtml+xml">
0 голосов
/ 17 июля 2010

Ваш XML-ввод не имеет встроенный XHTML, так как для этого потребуется, чтобы элементы, которые вы хотите распознать как XHTML, должны находиться в пространстве имен XHTML http://www.w3.org/1999/xhtml. Так что вам нужно либо изменить свой ввод чтобы поместить эти элементы в пространство имен XHTML, вы можете просто скопировать их из таблицы стилей в дерево результатов или изменить таблицу стилей, чтобы преобразовать эти элементы в элементы в пространстве имен XHTML. Следующее делает это, также делая некоторые другие изменения, такие как установка version = "1.0":

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/1999/xhtml">
<xsl:output 
  omit-xml-declaration="yes" 
  method="xml" 
  media-type="application/xhtml+xml" 
  indent="no" 
  doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
/>
<xsl:template match="Posts">
<xsl:for-each select="Post">
    <tr class="Post">
      <td>
        <div>
          <table width="100%" cellpadding="0" cellspacing="0">
            <tr>
              <td class="Author">
                <xsl:value-of select="Author"/>
              </td>
              <td class="Date">
                Post <xsl:value-of select="PostID"/> 
                <xsl:choose>
                  <xsl:when test="count(LastPost) > 0">
                    (lastpost)
                  </xsl:when>
                </xsl:choose> at <xsl:value-of select="Date"/>
              </td>
            </tr>
          </table>
        </div>
        <div class="Body">
           <xsl:apply-templates mode="to-xhtml" />
        </div>
        <xsl:choose>
          <xsl:when test="count(Sig) = 1">
            <div class="Sig">
              <xsl:value-of disable-output-escaping="yes" select="Sig"/>
            </div>
          </xsl:when>
          <xsl:when test="count(Sig) = 0">
            <div class="SigFooter"> </div>
          </xsl:when>
        </xsl:choose>
      </td>
    </tr>
</xsl:for-each>
</xsl:template>

<xsl:template match="Thread">
  <html>
    <head>
        <xsl:choose>
          <xsl:when test="count(Title) = 1">
            <title>
              <xsl:value-of select="Title"/>
            </title>
          </xsl:when>
        </xsl:choose>
        <link href="resources/main.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
      <table class="Thread" align="center" width="90%" height="95%" cellpadding="2em">
        <tr>
          <td colspan="3">
            <div class="Title">
          <xsl:value-of select="Title"/>
              <br />
              <a href="whatis.xml">
                <img src="resources/banner.png" />
              </a>
            </div>
          </td>
        </tr>
        <xsl:apply-templates select="Posts"/>
        <tr height="100%">
         <td valign="bottom">
       <div class="Footer">
             Footer message n stuff
           </div>
         </td>
        </tr>
      </table>
    </body>
  </html>
 </xsl:template>

  <xsl:template match="*" mode="to-xhtml">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@* | node()" mode="to-xhtml"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@* | text() | processing-instruction() | comment()" mode="to-xhtml">
    <xsl:copy/>
  </xsl:template>

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