2016-09-14 43 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對象。