2012-02-15 4 views
2

Представьте следующую ситуацию: мы получаем XML-файл из какого-либо внешнего инструмента. В последнее время в этом XML, может быть некоторые убежали charakters в nodenames или в пределах их richcontent тега, как в следующем примере (simplyfied):Unmarshalling XML с JAXB без несуществующих символов

<map> 
<node TEXT="Project"> 
<node TEXT="&#xe4;&#xe4;"> 
<richcontent TYPE="NOTE"><html> 
    <head> 

    </head> 
    <body> 
    <p> 
     I am a Note for Node &#228;&#228;! 
    </p> 
    </body> 
</html> 
</richcontent> 
</node> 
</node> 
</map> 

После демаршаллизации файла с JAXB этим уцелевшим charakters получить неэкранированное. К несчастью, мне нужно, чтобы они оставались такими, какими они есть, что означает бегство. Есть ли способ избежать отмены этих символов в то время, когда они не сортируются?

При исследовании я нашел много вопросов, касающихся сортировочных XML-файлы, где происходит противоположная проблема, но те не помогло мне либо:

Является ли это даже возможно ли достичь этой цели с помощью JAXB, или нам даже нужно рассмотреть возможность перехода на другой API-интерфейс xml?

Спасибо заранее, ymene

+0

Для любого синтаксического анализа XML не имеет значения, является ли источник документ содержит 'ä', 'ä' или '& # xe4', почему это имеет значение в вашем случае? –

+0

Проблема заключается в следующем: после импорта данных XML мы объединим его с нашими данными программы. Там мы изменим некоторые детали, а затем хотим записать эти данные обратно в xml для внешнего инструмента. Так как мы не создали еще один объектный график, чтобы просто вернуть данные в xml, мы обманули использование StAX, поскольку в это время это было просто проще. Так как до сих пор у нас никогда не было каких-либо экранированных символов, и к сожалению, внешний инструмент ожидает, что шаракеры еще не сработают. – crusam

ответ

2

Вам нужно только заменить &# на &amp;# поэтому называют

unmarshaller.unmarshal(new AmpersandingStream(new FileInputStream(...))); 

и

import java.io.IOException; 
import java.io.InputStream; 

/** 
* Replaces numerical entities with their notation as text. 
*/ 
public class AmpersandingStream extends InputStream { 

    private InputStream in; 
    private boolean justReadAmpersand; 
    private String lookAhead = ""; 

    public AmpersandingStream(InputStream in) { 
     this.in = in; 
    } 

    @Override 
    public int read() throws IOException { 
     if (!lookAhead.isEmpty()) { 
      int c = lookAhead.codePointAt(0); 
      lookAhead = lookAhead.substring(Character.charCount(c)); 
      return c; 
     } 
     int c = in.read(); 
     if (c == (int)'#' && justReadAmpersand) { 
      c = (int)'a'; 
      lookAhead = "mp;#"; 
     } 
     justReadAmpersand = c == (int)'&'; 
     return c; 
    } 

    @Override 
    public int available() throws IOException { 
     return in.available(); 
    } 

    @Override 
    public void close() throws IOException { 
     in.close(); 
    } 

    @Override 
    public synchronized void mark(int readlimit) { 
     in.mark(readlimit); 
    } 

    @Override 
    public boolean markSupported() { 
     return in.markSupported(); 
    } 

    @Override 
    public int read(byte[] b) throws IOException { 
     return in.read(b); 
    } 

    @Override 
    public int read(byte[] b, int off, int len) throws IOException { 
     return in.read(b, off, len); 
    } 

    @Override 
    public synchronized void reset() throws IOException { 
     in.reset(); 
    } 

    @Override 
    public long skip(long n) throws IOException { 
     return in.skip(n); 
    } 

} 
+1

Примечание: относительно легко создать документ, в котором этот подход повредит XML (например, кодирует как UTF-16, помещает амперсанды в разделы CDATA и т. Д.) – McDowell

+1

Вот вам тестовый пример: ''. –

+0

Код ищет последовательность '& #'. В CDATA это может быть проблематично, но JAXB и CDATA? В другом месте '&' всегда имеет смысл. –

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