Pergunta

Eu quero escrever algum texto que contém caracteres em branco como newline e tab em um arquivo xml então eu uso

Element element = xmldoc.createElement("TestElement");
element.appendChild(xmldoc.createCDATASection(somestring));

mas quando eu li isso novamente usando

Node vs =  xmldoc.getElementsByTagName("TestElement").item(0);
String x = vs.getFirstChild().getNodeValue();

Eu recebo uma cadeia que não tem newlines mais.
Quando eu olhar diretamente para o xml no disco, as novas linhas parecem preservada. de modo que o problema ocorre quando a leitura no arquivo xml.

Como posso preservar as quebras de linha?

Obrigado!

Foi útil?

Solução

Eu não sei como você analisar e escrever o seu documento, mas aqui está um exemplo de código aprimorado com base na sua:

// creating the document in-memory                                                        
Document xmldoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

Element element = xmldoc.createElement("TestElement");                                    
xmldoc.appendChild(element);                                                              
element.appendChild(xmldoc.createCDATASection("first line\nsecond line\n"));              

// serializing the xml to a string                                                        
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();             

DOMImplementationLS impl =                                                                
    (DOMImplementationLS)registry.getDOMImplementation("LS");                             

LSSerializer writer = impl.createLSSerializer();                                          
String str = writer.writeToString(xmldoc);                                                

// printing the xml for verification of whitespace in cdata                               
System.out.println("--- XML ---");                                                        
System.out.println(str);                                                                  

// de-serializing the xml from the string                                                 
final Charset charset = Charset.forName("utf-16");                                        
final ByteArrayInputStream input = new ByteArrayInputStream(str.getBytes(charset));       
Document xmldoc2 = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input);

Node vs =  xmldoc2.getElementsByTagName("TestElement").item(0);                           
final Node child = vs.getFirstChild();                                                    
String x = child.getNodeValue();                                                          

// print the value, yay!                                                                  
System.out.println("--- Node Text ---");                                                  
System.out.println(x);                                                                    

A serialização usando LSSerializer é a maneira W3C para fazê-lo ( veja aqui ). A saída é a esperada, com separadores de linha:

--- XML --- 
<?xml version="1.0" encoding="UTF-16"?>
<TestElement><![CDATA[first line
second line ]]></TestElement>
--- Node Text --- 
first line
second line

Outras dicas

Você precisa verificar o tipo de cada nó usando node.getNodeType (). Se o tipo é CDATA_SECTION_NODE, você precisa concat os guardas CDATA para node.getNodeValue.

Você não necessariamente tem que usar CDATA para preservar espaços em branco. O XML especificação especificar como codificar esses caracteres.

Assim, por exemplo, se você tem um elemento com valor que contém um novo espaço que você deve codificá-lo com

  &#xA;

Retorno de carro:

 &#xD;

E assim por diante

EDIT: corte todo o material irrelevante

Estou curioso para saber o que a implementação DOM que você está usando, porque não espelhar o comportamento padrão de um em um par de JVMs que eu tentei (eles navio com uma impl Xerces). Eu também estou interessado no que caracteres de nova linha o documento tiver.

Eu não tenho certeza se se CDATA deve preservar espaço em branco é um dado. Eu suspeito que há muitos fatores envolvidos. Não DTDs / esquemas afetar a forma como o espaço em branco é processado?

Você pode tentar usar o xml:. Space = "preserve" atributo

xml: space = 'preserve' não é isso. Isso é apenas para nós "todos os espaços em branco". Ou seja, se você deseja que o espaço em branco nós em

<this xml:space='preserve'> <has/>
<whitespace/>
</this>

Mas ver que esses nós de espaço em branco são apenas espaços em branco.

Eu tenho lutado para obter Xerces para gerar eventos que permitem o isolamento de conteúdo CDATA também. Eu não tenho nenhuma solução até agora.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top