2016-05-04 3 views
0

У меня есть документ HTML, который мне нужно преобразовать с помощью XSL. HTML-документ включает в себя использование   т.е.Объявить ENTITY, определяя nbsp как строку « »

ation.</span>&nbsp;</p><br/>All ... 

Во-первых, у меня были проблемы, потому что   не был определен. Так я определил это:

<?xml version=\"1.0\"?> 
<!DOCTYPE html [ 
    <!ENTITY nbsp "&#160;"> 
"]> 

Я сделал так, предваряя этот код в HTML строку перед отправкой его к трансформации. После преобразования объявление ENTITY было удобно исчезло, и, да, отлично, преобразование действительно сработало.

Однако! Поскольку nbsp был определен как пробел, сгенерированный HTML/XML видел, что строки "&nbsp;" фактически заменены символом пробела.

Это не то, что я хочу. Мне нужно, чтобы часть результата не отличалась от источника.

Итак, я попытался переосмысление NBSP, например, так:

<?xml version=\"1.0\"?> 
<!DOCTYPE html [ 
    <!ENTITY nbsp "&amp;nbsp;"> 
"]> 

Однако теперь вместо пробела в моем результате, я вижу персонажей "&amp;nbsp;"

Если я пытаюсь это:

<?xml version=\"1.0\"?> 
<!DOCTYPE html [ 
    <!ENTITY nbsp "&nbsp;"> 
"]> 

Я получаю исключение рекурсивного объявления.

Как включить в определение специальный символ '&'?

p.s., это преобразование Я работаю в Java 8, по умолчанию (по-моему, это xalan?).

Спасибо всем!

Ниже приведен краткий пример того, как воспроизводить. Извините, что не предоставлял его раньше.


package com.astraia.app.mainframe; 

import java.io.*; 
import javax.xml.transform.*; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.transform.stream.StreamSource; 

public class ShortExample 
{ 
    public static void main(String[] args) 
    { 
     StringBuffer htmlMain = new StringBuffer(500); 
     htmlMain .append("<html><head></head>") 
        .append(" <body>)") 
        .append("  <p data-tags=\"personal\"><strong>name: Nerea Morry, Id: 5678</strong><br/></p>") 
        .append("  <p><span>some text</span>&nbsp;</p><br/>some more text") 
        .append(" </body>") 
        .append("</html>"); 

     StringBuffer xsl = new StringBuffer(500); 
     xsl .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") 
      .append("<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">") 
      .append(" <xsl:output method=\"xml\" version=\"1.0\" encoding=\"UTF-8\" omit-xml-declaration=\"yes\" />") 
      .append(" <xsl:template match=\"node()|@*\" >") 
      .append("  <!-- Copy all nodes -->") 
      .append("  <xsl:copy>") 
      .append("    <xsl:apply-templates select=\"node()|@*\" />") 
      .append("  </xsl:copy>") 
      .append(" </xsl:template>") 
      .append(" <!-- Anonymize all text within tags indicated as personal -->") 
      .append(" <xsl:template match=\"*[@data-tags = 'personal' ]//text()[normalize-space(.) != '']\">ANONYMIZED TEXT</xsl:template>") 
      .append(" </xsl:stylesheet>"); 

     String plainHtml = htmlMain.toString(); 
     String transformation = xsl.toString(); 

     // results in &nbsp being replaced by a space 
     printResult("results in &nbsp being replaced by a space", plainHtml,"&#160;", transformation); 
     // results in seemingly non-replaced escape code &amp; 
     printResult("results in seemingly non-replaced escape code &amp;", plainHtml,"&amp;nbsp", transformation); 
     // results in recursion exception 
     printResult("results in recursion exception", plainHtml,"&nbsp;", transformation); 
     // also results in recursion exception 
     printResult("also results in recursion exception", plainHtml,"&#038;nbsp;", transformation); 

     // but what will result in: 
     // <html><head/> <body>)  <p data-tags="personal"><strong>ANONYMIZED TEXT</strong><br/></p>  <p><span>some text</span>&nbsp</p><br/>some more text </body></html> 
     // ? 
    } 

    public static void printResult(String message, String plainHtml, String definition, String transformation) { 
     System.out.print(message); 
     System.out.println(performTransformation(plainHtml,definition, transformation)); 
     System.out.println("\n-----"); 
    } 

    public static String performTransformation(String plainHtml, String definition, String transformation) 
    { 
     String retval = null; 

     try { 
      StringWriter result = new StringWriter(); 
      StringBuffer header = new StringBuffer(100); 
      header .append("<?xml version=\"1.0\"?>") 
        .append("<!DOCTYPE html [") 
        .append(" <!ENTITY nbsp REPLACE_ME>") 
        .append("]>\n"); 

      String headerText = header.toString().replace("REPLACE_ME", "\"" + definition + "\""); 
      String wholeText = new StringBuffer(headerText).append(plainHtml).toString(); 

      TransformerFactory factory = TransformerFactory.newInstance(); 
      Source xslt = new StreamSource(new StringReader(transformation)); 
      Transformer transformer = factory.newTransformer(xslt); 
      Source text = new StreamSource(new StringReader(wholeText)); 
      transformer.transform(text, new StreamResult(result)); 
      retval = result.toString(); 
     } 
     catch (Exception e) { 
      System.out.println(e.getMessage()); 
     } 

     return retval; 
    } 
} 

Вот выход из моего запуска моего маленького примера приложения:

results in &nbsp being replaced by a space<html><head/> <body>)  <p data-tags="personal"><strong>ANONYMIZED TEXT</strong><br/></p>  <p><span>some text</span> </p><br/>some more text </body></html> 

----- 
results in seemingly non-replaced escape code &amp;<html><head/> <body>)  <p data-tags="personal"><strong>ANONYMIZED TEXT</strong><br/></p>  <p><span>some text</span>&amp;nbsp</p><br/>some more text </body></html> 

----- 
results in recursion exceptionjavax.xml.transform.TransformerException: com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Recursive entity reference "nbsp". (Reference path: nbsp -> nbsp -> nbsp), 
null 
ERROR: 'Recursive entity reference "nbsp". (Reference path: nbsp -> nbsp -> nbsp),' 
----- 
ERROR: 'com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Recursive entity reference "nbsp". (Reference path: nbsp -> nbsp -> nbsp),' 

also results in recursion exceptionERROR: 'Recursive entity reference "nbsp". (Reference path: nbsp -> nbsp -> nbsp),' 
ERROR: 'com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Recursive entity reference "nbsp". (Reference path: nbsp -> nbsp -> nbsp),' 
javax.xml.transform.TransformerException: com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Recursive entity reference "nbsp". (Reference path: nbsp -> nbsp -> nbsp), 
null 

----- 

Разница между 4 попыток являются:

</span> </p><br/>some more text 

</span>&amp;nbsp</p><br/>some more text 

exception 

exception 
+0

«* Поскольку nbsp был определен как пробел *« Вы показываете 'nbsp', определяемый не как пробел, а как неразрывное пространство - и преобразование должно его сохранять (если вы не сделали что-то, чтобы перевести его в пространство явно). Пожалуйста, напишите ** воспроизводимый пример ** - см.: [Mcve] –

+0

Какую версию XSLT вы используете и какой процессор используете для ее обработки? –

+0

@ michael.hor257k - да, извините, я обновил свой пост сейчас тем, что, надеюсь, является достаточно коротким и минимальным воспроизводимым примером. – svaens

ответ

1

Я считаю, у вас есть два варианта:

  1. Измените способ вывода на html;
    Это будет выводить любое неразрывное пространство как &nbsp;

  2. Изменения выходного кодирования для ASCII;
    Это будет выводить любой неразрывный пробел, как &#160;


Примечание: Если оставить метод вывода как xml и кодирование как UTF-8, сериализованные результат должен еще включать неэкранированный неразрывное пространство. В вашей цепочке обработки может быть что-то еще, что предотвратит это, или, может быть, вы ошибаетесь в характере для обычного пространства (в конце концов, в большинстве случаев они отображаются одинаково).

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