2014-10-31 8 views
0

Я хотел бы объединить два org.w3c.dom.Document с, у меня есть что-то вроде этого:Объединить два org.w3c.dom.Document

Document finalDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() 
Document document1 = createDocumentOne(); 
Document document2 = createDocumentTwo(); 

// This didn't work 
changeFileDocument.appendChild(document1); 
changeFileDocument.appendChild(document2); 

Формат документа1 и документ2 это что-то вроде это:

<headerTag> 
    <tag1>value</tag1> 
</headerTag> 

И то, что я хочу, в конце концов, документ, как это:

<headerTag> 
    <tag1>valueForDocument1</tag1> 
</headerTag> 
<headerTag> 
    <tag1>valueForDocument2</tag1> 
</headerTag> 

Я думаю, что вы не можете сделать это, потому что у них должен быть общий родитель. Если это так, я хотел бы создать этого «поддельного» родителя, объединить файлы, но потом восстановить только список элементов headerTag

Как это сделать?

+0

является 'headerTag' ваш корневой элемент? если не то, что является корневым элементом? – A4L

+0

вам нужен корневой элемент для создания надлежащего XML-документа. Если это не xml, укажите язык разметки, на котором он создается. кроме того, почему вы не конвертируете org.w3c.Document (s) в соответствующие файлы String и не объединяете их и, наконец, не делаете из него еще один экземпляр org.w3c.Document. –

+0

@ A4L, «headerTag» является корневым элементом Документов, созданных методами «createDocument1» и «createDocument2», и единственное, что я хочу, это конкатенация один за другим, даже если мне нужно создать родитель root. – Manuelarte

ответ

1

Вы были на правильном пути с создания нового документа, разбор части и добавить тир узлы новыми.

Вы подходите неудачно, потому что пытаетесь добавить целый документ к другому, что невозможно.

Вы могли бы попробовать что-то вроде этого:

public org.w3c.dom.Document concatXmlDocuments(String rootElementName, InputStream... xmlInputStreams) throws ParserConfigurationException, SAXException, IOException { 
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
    org.w3c.dom.Document result = builder.newDocument(); 
    org.w3c.dom.Element rootElement = result.createElement(rootElementName); 
    result.appendChild(rootElement); 
    for(InputStream is : xmlInputStreams) { 
     org.w3c.dom.Document document = builder.parse(is); 
     org.w3c.dom.Element root = document.getDocumentElement(); 
     NodeList childNodes = root.getChildNodes(); 
     for(int i = 0; i < childNodes.getLength(); i++) { 
      Node importNode = result.importNode(childNodes.item(i), true); 
      rootElement.appendChild(importNode); 
     } 
    } 
    return result; 
} 

Кода выше копий всех узлов, найденных в корневом элементе каждого документа. Конечно, вы можете выбрать выборочную копию только интересующих вас узлов. В результате документ отобразит все узлы обоих документов.

Тест

@Test 
public void concatXmlDocuments() throws ParserConfigurationException, SAXException, IOException, TransformerException { 
    try (
      InputStream doc1 = new ByteArrayInputStream((
       "<headerTag>\r\n" + 
       " <tag1>doc1 value</tag1>\r\n" + 
       "</headerTag>").getBytes(StandardCharsets.UTF_8)); 
      InputStream doc2 = new ByteArrayInputStream((
       "<headerTag>\r\n" + 
       " <tag1>doc2 value</tag1>\r\n" + 
       "</headerTag>").getBytes(StandardCharsets.UTF_8)); 
      ByteArrayOutputStream docR = new ByteArrayOutputStream(); 

     ) { 

     org.w3c.dom.Document result = concatXmlDocuments("headerTag", doc1, doc2); 
     TransformerFactory trf = TransformerFactory.newInstance(); 
     Transformer tr = trf.newTransformer(); 
     tr.setOutputProperty(OutputKeys.INDENT, "yes"); 
     DOMSource source = new DOMSource(result); 
     StreamResult sr = new StreamResult(docR); 
     tr.transform(source, sr); 
     System.out.print(new String(docR.toByteArray(), StandardCharsets.UTF_8)); 
    } 
} 

Выход

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<headerTag> 
    <tag1>doc1 value</tag1> 
    <tag1>doc2 value</tag1> 
</headerTag> 

EDIT

Я хотел бы создать, что "поддельные" родитель, конкатенации файлов, бушель т, то только восстановить список элементов headerTag

Как вы говорите, создать поддельный родителя.Вот как можно это сделать:

1) У конкатенацию

public org.w3c.dom.Document concatXmlDocuments(InputStream... xmlInputStreams) throws ParserConfigurationException, SAXException, IOException { 
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
    org.w3c.dom.Document result = builder.newDocument(); 
    org.w3c.dom.Element rootElement = result.createElement("fake"); 
    result.appendChild(rootElement); 
    for(InputStream is : xmlInputStreams) { 
     org.w3c.dom.Document document = builder.parse(is); 
     org.w3c.dom.Element subRoot = document.getDocumentElement(); 
     Node importNode = result.importNode(subRoot, true); 
     rootElement.appendChild(importNode); 
    } 
    return result; 
} 

2) Восстановить список узлов для headerTag

public NodeList recoverTheListOfElementsHeaderTag(String xml) throws ParserConfigurationException, SAXException, IOException { 
    NodeList listOfElementsHeaderTag = null; 
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
    try (InputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) { 
     listOfElementsHeaderTag = recoverTheListOfElementsHeaderTag(builder.parse(is)); 
    } 
    return listOfElementsHeaderTag; 
} 

public NodeList recoverTheListOfElementsHeaderTag(org.w3c.dom.Document doc) { 
    org.w3c.dom.Element root = doc.getDocumentElement(); 
    return root.getChildNodes(); 
} 

Test

@Test 
public void concatXmlDocuments() throws ParserConfigurationException, SAXException, IOException, TransformerException { 
    try (
      InputStream doc1 = new ByteArrayInputStream((
       "<headerTag>" + 
       "<tag1>doc1 value</tag1>" + 
       "</headerTag>").getBytes(StandardCharsets.UTF_8)); 
      InputStream doc2 = new ByteArrayInputStream((
       "<headerTag>" + 
       "<tag1>doc2 value</tag1>" + 
       "</headerTag>").getBytes(StandardCharsets.UTF_8)); 

     ) { 

     org.w3c.dom.Document result = concatXmlDocuments(doc1, doc2); 
     String resultXML = toXML(result); 
     System.out.printf("%s%n", resultXML); 
     NodeList listOfElementsHeaderTag = null; 
     System.out.printf("===================================================%n"); 
     listOfElementsHeaderTag = recoverTheListOfElementsHeaderTag(resultXML); 
     printNodeList(listOfElementsHeaderTag); 
     System.out.printf("===================================================%n"); 
     listOfElementsHeaderTag = recoverTheListOfElementsHeaderTag(result); 
     printNodeList(listOfElementsHeaderTag); 
    } 
} 


private String toXML(org.w3c.dom.Document result) throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException, IOException { 
    String resultXML = null; 
    try (ByteArrayOutputStream docR = new ByteArrayOutputStream()) { 
     TransformerFactory trf = TransformerFactory.newInstance(); 
     Transformer tr = trf.newTransformer(); 
     DOMSource source = new DOMSource(result); 
     StreamResult sr = new StreamResult(docR); 
     tr.transform(source, sr); 
     resultXML = new String(docR.toByteArray(), StandardCharsets.UTF_8); 
    } 
    return resultXML; 
} 

private void printNodeList(NodeList nodeList) { 
    for(int i = 0; i < nodeList.getLength(); i++) { 
     printNode(nodeList.item(i), ""); 
    } 
} 

private void printNode(Node node, String startIndent) { 
    if(node != null) { 
     System.out.printf("%s%s%n", startIndent, node.toString()); 
     NodeList childNodes = node.getChildNodes(); 
     for(int i = 0; i < childNodes.getLength(); i++) { 
      printNode(childNodes.item(i), startIndent+ " "); 
     } 
    } 
} 

Выход

<?xml version="1.0" encoding="UTF-8" standalone="no"?><fake><headerTag><tag1>doc1 value</tag1></headerTag><headerTag><tag1>doc2 value</tag1></headerTag></fake> 
=================================================== 
[headerTag: null] 
    [tag1: null] 
     [#text: doc1 value] 
[headerTag: null] 
    [tag1: null] 
     [#text: doc2 value] 
=================================================== 
[headerTag: null] 
    [tag1: null] 
     [#text: doc1 value] 
[headerTag: null] 
    [tag1: null] 
     [#text: doc2 value] 
+0

Привет @ A4L, спасибо за ваш комментарий, но это не тот результат, который мне интересен. Я заинтересован в ' значение dic1 значение doc2 ' – Manuelarte

+0

@Manuelarte, ОК, то зачем с XML разборе? нужный вам результат недействителен XML, тогда корневой тег появляется два раза или нет корневого тега, поэтому просто читайте оба файла как текст и применяйте оператор '+'. Если вам нужно проанализировать его впоследствии как XML, вам нужно будет обернуть его в корневой тег, имя которого не является 'headerTag', тогда вы можете получить нужные вам узлы с помощью' Document # getDocumentElement(). GetElementsByTagName ("tag1") ; ' – A4L

+0

@Manuelarte, я отредактировал свой ответ, надеюсь, что он отражает ваши требования. – A4L

1

Как вы говорите, у вас должен быть один корневой узел, и вам нужно импортировать другие документы. Например:

Element root = finalDocument.createElement("root"); 
finalDocument.appendChild(root); 
root.appendChild(
    finalDocument.importNode(document1.getDocumentElement(), true)); 
root.appendChild(
    finalDocument.importNode(document2.getDocumentElement(), true)); 
+0

И затем, я извлекаю элемент, который меня интересует, используя finalDocument.changeFileDocument.getChildNodes() ?? я? – Manuelarte

+0

@Manuelarte: Ну, совершенно непонятно, что означает 'changeFileDocument', или что вы подразумеваете под« интересующим меня элементом ». –

+0

вы создаете XML-документ, используя методы createDocument1(), createDocument2(). И тогда вы хотите объединить их в один документ, известный как finalDocument. Позже я хочу восстановить из finalDocument только узлы. Яснее? – Manuelarte

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