2016-05-18 4 views
0

У меня есть XML-файл, и мне нужно удалить определенный узел. Узел, который будет удален, будет определяться динамически на основе логики. Я искал в Интернете решение, но не смог удалить мой узел. am get error - NOT_FOUND_ERR: An attempt is made to reference a node in a context where it does not existНевозможно удалить определенный узел в XML

Ниже приведен пример XML-файла. Мне нужно удалить узел <NameValuePairs>, который имеет <name>Local Variables</name>. Ниже мой пример XML файлы Java Code

Пример XML файла

<?xml version="1.0" encoding="UTF-8"?> 
<DeploymentDescriptors xmlns="http://www.tibco.com/xmlns/dd"> 
<name>Test</name> 
<version>1</version> 
<DeploymentDescriptorFactory> 
    <name>RepoInstance</name> 
</DeploymentDescriptorFactory> 
<DeploymentDescriptorFactory> 
    <name>NameValuePairs</name> 
</DeploymentDescriptorFactory> 
<NameValuePairs> 
    <name>Global Variables</name> 
    <NameValuePair> 
     <name>Connections1</name> 
     <value>7222</value> 
     <requiresConfiguration>true</requiresConfiguration> 
    </NameValuePair> 
    <NameValuePair> 
     <name>Connections2</name> 
     <value>7222</value> 
     <requiresConfiguration>true</requiresConfiguration> 
    </NameValuePair> 
</NameValuePairs> 
<NameValuePairs> 
    <name>Local Variables</name> 
    <NameValuePair> 
     <name>Connections3</name> 
     <value>8222</value> 
     <requiresConfiguration>true</requiresConfiguration> 
    </NameValuePair> 
    <NameValuePair> 
     <name>Connections3</name> 
     <value>8222</value> 
     <requiresConfiguration>true</requiresConfiguration> 
    </NameValuePair> 
</NameValuePairs> 
</DeploymentDescriptors> 

Java Code

File fDestFile = new File("myfile.xml"); 
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 
Document oDoc3 = dBuilder.parse(fDestFile); 
NodeList oDestFlowList = oDoc3.getElementsByTagName("NameValuePairs"); 
for (int m = 0; m < oDestFlowList.getLength(); m++) { 
    NodeList oDestchildList = oDestFlowList.item(m).getChildNodes(); 
    for (int n = 0; n < oDestchildList.getLength(); n++) { 
      Node oDestchildNode = oDestchildList.item(n); 
      if ("name".equals(oDestchildNode.getNodeName())) { 
      //oDestchildNode.getParentNode().removeChild(oDestchildNode); //Not Working 
      //oDoc3.getDocumentElement().removeChild(oDestchildNode); //Not Working 
      } 
     } 
    } 
} 
+0

, какая строка кода, генерирующую ошибку? – jtahlborn

+0

У меня нет ошибок. Детский элемент, который я пытаюсь удалить, не удаляется с помощью вышеуказанного кода. – Lettisha

ответ

1

Вот окончательный кусок кода, который, наконец, работал

public static void main(String[] args) { 
    File fXmlSubFile = new File("Sub.xml"); 
    File fXmlOriginalFile = new File("Original.xml"); 
    File fDestFile = new File("myfile.xml"); 
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder dBuilder; 
    FileChannel source = null; 
    FileChannel destination = null; 
    XPath xPath = XPathFactory.newInstance().newXPath(); 

    try{ 
     if (!fDestFile.exists()) { 
      fDestFile.createNewFile(); 
     } 
     source = new FileInputStream(fXmlOriginalFile).getChannel(); 
     destination = new FileOutputStream(fDestFile).getChannel(); 
     if (destination != null && source != null) { 
      destination.transferFrom(source, 0, source.size()); 
     } 
     if (source != null) { 
      source.close(); 
     } 
     if (destination != null) { 
      destination.close(); 
     } 
     dBuilder = dbFactory.newDocumentBuilder(); 
     Document oSubDoc = dBuilder.parse(fXmlSubFile); 
     Document oDestDoc = dBuilder.parse(fDestFile); 
     oSubDoc.getDocumentElement().normalize(); 
     oDestDoc.getDocumentElement().normalize(); 

     String sDestExpression = "/DeploymentDescriptors/NameValuePairs"; 
     String sSubExpression = "/NameValuePairs"; 
     NodeList nodeDestList = (NodeList) xPath.compile(sDestExpression).evaluate(oDestDoc, XPathConstants.NODESET); 
     NodeList nodeSubList = (NodeList) xPath.compile(sSubExpression).evaluate(oSubDoc, XPathConstants.NODESET); 
     for (int i = nodeDestList.getLength()-1; i >=0 ; i--) { 
      Node oDestNode = nodeDestList.item(i); 
      if (oDestNode.getNodeType() == Node.ELEMENT_NODE) { 
       Element oDestElement = (Element) oDestNode; 
       for (int j =0; j<nodeSubList.getLength(); j++) { 
        Node oSubNode = nodeSubList.item(j); 
        if (oSubNode.getNodeType() == Node.ELEMENT_NODE) { 
         Element oSubElement = (Element) oSubNode; 
         if(oDestElement.getElementsByTagName("name").item(0).getTextContent().equals(oSubElement.getElementsByTagName("name").item(0).getTextContent())){ 
         oDestNode.getParentNode().removeChild(oDestNode); 
         } 
        } 
       } 
      } 
     } 
     Source src = new DOMSource(oDestDoc); 
     Result result = new StreamResult(fDestFile); 
     Transformer transformer = null; 
     transformer = TransformerFactory.newInstance().newTransformer(); 
     // Transform your XML document (i.e. save changes to file) 
     transformer.transform(src, result); 
    }catch(Exception ex){ 
     System.out.println("error:"+ex.getMessage()); 
     ex.printStackTrace(); 
    } 
} 
1

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

File fDestFile = new File("src/myfile.xml"); 
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder dBuilder = null; 
    try { 
     dBuilder = dbFactory.newDocumentBuilder(); 
     Document oDoc3 = null; 
     oDoc3 = dBuilder.parse(fDestFile); 
     NodeList oDestFlowList = oDoc3.getElementsByTagName("NameValuePairs"); 
     // Loop through all 'NameValuePairs' 
     for (int m = oDestFlowList.getLength()-1; m >=0 ; m--) { 
      NodeList oDestchildList = oDestFlowList.item(m).getChildNodes(); 
      // Loop through children of 'NameValuePairs' 
      for (int n = oDestchildList.getLength()-1; n >=0 ; n--) { 
       // Remove children if they are of the type 'name' 
       if(oDestchildList.item(n).getNodeName().equals("name")){ 
        oDestFlowList.item(m).removeChild(oDestchildList.item(n)); 
        // For debugging 
        System.out.println(oDestchildList.item(n).getNodeName()); 
       } 
      } 
     } 
     Source source = new DOMSource(oDoc3); 
     Result result = new StreamResult(fDestFile); 
     Transformer transformer = null; 
     transformer = TransformerFactory.newInstance().newTransformer(); 
     // Transform your XML document (i.e. save changes to file) 
     transformer.transform(source, result); 
    } catch (Exception e) { 
     // Catch the exception here 
     e.printStackTrace(); 
    } 
} 

Если у вас все еще есть проблемы, тогда я wo uld считает, что это проблема с типами узлов. Это работало для меня, прежде чем я поставил чек на «oDestchildNode.getNodeType()», но я бы посмотрел, какой тип узла вы возвращаетесь и оттуда.

+0

Спасибо за ваш быстрый ответ. Я пробовал ваше решение, но мы не можем назначить узел элементу. Я получаю ошибку кастинга с помощью элемента Element node = (Element) oDestchildList.item (i); – Lettisha

+0

Я получаю ошибку литья после попытки использования ниже 2 опций Вариант 1: Элемент node = (Элемент) oDestchildList.item (i); Элемент elemenet = node.getParentNode(); Вариант 2: Узел oDestchildNode = oDestchildList.item (n); Элемент elemenet = oDestchildNode.getParentNode(); Может кто-нибудь, пожалуйста, помогите мне исправить это – Lettisha

+0

Вы используете класс 'org.w3c.dom.Element'? – ghg565

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