RemoveChild удаляет первого потомка с таким именем, но пропускает следующего с тем же именем - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть этот узел

<Record status="updated">
    <ID_Country>5</ID_Country>
    <ID_Currency>162</ID_Currency>
    <IsoCodeNumber>16  </IsoCodeNumber>
    <IsoCodeLetter version="old">AS  </IsoCodeLetter>
    <IsoCodeLetter version="new">ASAS  </IsoCodeLetter>
    <PostCode>    </PostCode>
    <CountryName>American Samoa  </CountryName>                        
    <isEuCountry>0</isEuCountry>
</Record>

Я пытаюсь добавить этот узел в другой XML-файл и выглядеть следующим образом.

<Record>
     <ID_Country>5</ID_Country>
     <ID_Currency>162</ID_Currency>
     <IsoCodeNumber>16  </IsoCodeNumber>         
     <IsoCodeLetter>ASAS  </IsoCodeLetter>
     <PostCode>    </PostCode>
     <CountryName>American Samoa  </CountryName>                        
     <isEuCountry>0</isEuCountry>
</Record>

Это код, который я использую

Node updatedNode = diffNode.cloneNode(true);
((Element) updatedNode).removeAttribute("status");    

for (int i = 0; i < updatedNode.getChildNodes().getLength(); i++)
{
    if (updatedNode.getChildNodes().item(i).getNodeType() == Node.ELEMENT_NODE)
    {                           
         Element e = (Element)updatedNode.getChildNodes().item(i);
         String string = e.getNodeName();

         if (e.hasAttribute("version") && e.getAttribute("version").equals("old"))
         {                 
              ((Element) updatedNode).removeChild((Node)e);                                
         }
         if(e.hasAttribute("version") && e.getAttribute("version").equals("new"))
         {              
               e.removeAttribute("version");
         }
    }
} 
productXML.adoptNode(updatedNode);
prodRoot.insertBefore(updatedNode, nextNode);

По какой-то причине, когда цикл проходит через первый узел IsoCodeLetter и удаляет его, он пропускает следующий и переходит к PostCode, но второй IsoCodeLetter все еще находится в новом узле, к которому я добавляюXML-файл и выглядит следующим образом.

<Record>
      <ID_Country>5</ID_Country>
      <ID_Currency>162</ID_Currency>
      <IsoCodeNumber>16  </IsoCodeNumber>         
      <IsoCodeLetter version="new">ASAS  </IsoCodeLetter>
      <PostCode>    </PostCode>
      <CountryName>American Samoa  </CountryName>                        
      <isEuCountry>0</isEuCountry>
</Record>

У вас есть идеи, почему это происходит и как это исправить?Я использую DOMParser для записи файла XML.

1 Ответ

0 голосов
/ 05 декабря 2018

Удаляя дочерний элемент из элемента, вы удаляете его из дочерних узлов, что означает, что следующий дочерний элемент теперь находится в индексе дочернего элемента, который вы удалили.Но ваш цикл продолжается с индексом next , пропуская этого потомка.Например: предположим, у вас есть:

0: Child A
1: Child B
2: Child C
3: Child D

Для i == 0, допустим, вы не удаляете Child A. Ваш цикл добавляет один к i и вы продолжаете с i == 1.Вы делаете удаления ребенка B. Теперь у вас есть:

0: Child A
1: Child C
2: Child D

.. но ваш цикл добавляет один к i и теперь i == 2, и следующий ребенок, на которого вы смотрите, это ChildD. Вы никогда не смотрели на Дитя С.

Обычные решения:

  1. Цикл назад, поэтому индекс уменьшается, и поэтому это не имеет значенияудаляете ли вы ребенка по указанному индексу;или

  2. Сделайте снимок списка дочерних узлов перед изменением элемента, чтобы при удалении дочернего элемента из элемента он не удалялся изваш снимок

Переход назад довольно прост:

for (int i = updatedNode.getChildNodes().getLength() - 1; i >= 0; i--)

Примечание: я бы, вероятно, также позвонил getChildNodes просто один раз и повторно использовать полученный NodeList объект:

NodeList children = updatedNode.getChildNodes();
for (int i = children.getLength() - 1; i >= 0; i--)
    // ...and use `children`, not `updatedNode.getChildNodes()`, in the loop body...
}
...