2016-09-14 48 views
1

我正在做一些使用XMLEventReaderXMLEventWriter的手术XML转换。在大多数情况下,我只写事件因为他们正在阅读:在XMLEventWriter中编码属性换行

import javax.xml.stream.*; 
import javax.xml.stream.events.XMLEvent; 
import java.io.StringReader; 
import java.io.StringWriter; 

public class StaxExample { 
    public static void main(String[] args) throws XMLStreamException { 
     String inputXml = 
       "<foo>" + 
       " <bar baz=\"a&#10;b&#10;c&#10;\"/>" + 
       " <changeme/>" + 
       "</foo>"; 

     StringWriter result = new StringWriter(); 

     XMLEventReader reader = XMLInputFactory.newFactory().createXMLEventReader(new StringReader(inputXml)); 
     XMLEventWriter writer = XMLOutputFactory.newFactory().createXMLEventWriter(result); 

     while (reader.hasNext()) { 
      XMLEvent event = reader.nextEvent(); 
      //in real code, look for "changeme" and insert some stuff 
      writer.add(event); 
     } 

     System.out.println(result.toString()); 
    } 
} 

我的问题是,这将产生:

<?xml version="1.0" ?><foo> <bar baz="a 
b 
c 
"></bar> <changeme></changeme></foo> 

虽然语法有效的XML,这是必要的(由于下游消费)我保留换行符。上面的XML将被该消费者标准化为a b c(事实上,StAX本身 - 如果我接收该输出并将其反馈回相同的程序中,则第二次将输出baz="a b c ")。

尽管我已经放弃保留非语义格式的XMLEventWriter,有没有办法阻止它实质上改变我的属性值?

+0

XMLStreamReader/Writer的相似问题:http://stackoverflow.com/questions/8331364/how-to-preserve-whitespace-in-attributes-when-using-xmlstreamwriter。那里也没有答案。 –

回答

0

好吧,我建议你实现自己的作家:

public class EscappingNLWriter extends FilterWriter 
{ 
    public EscappingNLWriter(Writer out) {super(out);} 

    public void write(c) 
    { 
     if (c=='\n') 
     { 
      out.write("&#10;"); 
     } 
     else 
     { 
      out.write(c); 
     } 
    } 

    public void write(char[] buff, int offset, int len) throws IOException 
    { 
     // ...Same char filtering... 
    } 

    public void write(String str, int offset, int len) throws IOException 
    { 
     // ...Same char filtering... 
    } 
} 

,然后用它来封装的StringWriter:

Writer result = new EscappingNLWriter(new StringWriter()); 
+0

嗨,感谢您的关注和答复!我不确定这将是多么实际,因为它也会替换标签内的换行符(例如标签中的属性之间),而不仅仅是字符数据。是否真的安全/相当于用数字引用替换文档中遇到的所有*换行符? –

+0

是的,全部。在XML文件的任何位置,数字实体在词法上等同于它们表示的符号。 –

+0

在CDATA部分怎么样? –

0

如果你需要一个绝对精度哪里到在XML和中脱离换行符,其中不是(即:只需在属性中而不是在其他地方转义换行符),我已经Ë另一项建议艰难更复杂一点:

看看你的代码:

while (reader.hasNext()) { 
     XMLEvent event = reader.nextEvent(); 
     //in real code, look for "changeme" and insert some stuff 
     writer.add(event); 
    } 

有一个地步,你可以干预的属性和作家之间:只是初始化event后传递之前,到writer.add,你可以封装事件在你自己的执行XMLEvent,以确保如果它是一个javax.xml.stream.events.Attribute的实例,你将覆盖Attribute.getValue()返回适当的escapped值。

但有一个额外的复杂因素:由XMLEventReader返回的XMLEvents通常不包含属性事件:属性包含在其相应的StartElement事件中。所以你需要更多级别的封装:StartElement对象,然后是包含的Attribute对象。