how to replace a child node with another child node in an XML file?

2 views (last 30 days)

Hi,

I have an XML snippet in the following format.

               </Markings>
               <Profiles>
                  <Profile name="LAKECITY_2x2voies+tp+park+trottoir" type="none">
                     <LaneBorder distance="-15.1 " height="0.15 " markingOffset="0 "/>
                     <LaneBorder distance="-12.15 " height="0.15 " markingOffset="0 "/>
                     <LaneBorder distance="-12.1 " height="0 " markingOffset="0.15 "/>
                     <LaneBorder distance="-11.8 " height="0 " markingOffset="0 "/>
                     <Lane Ground="Cobblestone " circulationWay="both " name="Lane " speedLimit="8.33333 " type="sidewalk "/>
                     <Lane Ground="Asphalt " circulationWay="none " name="Lane 2 " speedLimit="0 " type="shoulder "/>
                     <Lane Ground="Asphalt " circulationWay="none " name="Lane 3 " speedLimit="0 " type="shoulder "/>
                     <Lane Ground="Asphalt " circulationWay="inverse " name="Lane 4 " speedLimit="13.8888888888889 " type="parking "/>
                     <Lane Ground="Asphalt " circulationWay="none " name="Lane 3 " speedLimit="0 " type="shoulder "/>                  </Profile>
               </Profiles>
            </RoadNetwork>

As can be seen from the snippet, the arrangement of the nodes is such that all the LaneBorder nodes are listed at first and then the Lane nodes. I am trying to change this format in such a way that the LaneBorder nodes and Lane nodes alternate thelselves like shown in the snippet below:

              <Profiles>
                  <Profile name="LAKECITY_2x2voies+tp+park+trottoir" type="none">
                     <LaneBorder distance="-15.1 " height="0.15 " markingOffset="0 "/>
                     <Lane Ground="Cobblestone " circulationWay="both " name="Lane " speedLimit="8.33333 " type="sidewalk "/>
                     <LaneBorder distance="-12.15 " height="0.15 " markingOffset="0 "/>
                     <Lane Ground="Asphalt " circulationWay="none " name="Lane 2 " speedLimit="0 " type="shoulder "/>
                     <LaneBorder distance="-12.1 " height="0 " markingOffset="0.15 "/>
                     <Lane Ground="Asphalt " circulationWay="none " name="Lane 3 " speedLimit="0 " type="shoulder "/>
                     <LaneBorder distance="-11.8 " height="0 " markingOffset="0 "/>                     
                     <Lane Ground="Asphalt " circulationWay="inverse " name="Lane 4 " speedLimit="13.8888888888889 " type="parking "/>
                  </Profile>
               </Profiles>

I tried the following steps to achieve this:

    profilesNode = docNode.getElementsByTagName('Profiles'); %Get all the 'Profiles' in the document
    prof1 = profileNodeCol.item(0); %Getting the first 'Profile' node
    LaneCollection = prof1.getElementsByTagName('Lane'); %Getting all the 'Lane' nodes inside 'Profile'
    LBcollection = prof1.getElementsByTagName('LaneBorder'); %Getting all the 'LaneBorder' nodes inside 'Profile'
    prof1ChildNodes = prof1.getChildNodes; %Getting all the childNodes inside 'Profile'
    prof1ChildNodes.replaceChild(LaneCollection.item(0),prof1ChildNodes.item(1)) %Trying to replace the second childNode of Profile with first 'Lane' node

When i tried this, all that happened was that the count inside "prof1ChildNodes" kept on reducing. It was 16 at first and then it kept on reducing with the number of replacements that i tried.

Is there any way in which i can acheive this functionality? Any assistance would be of great help!!!

Thanks in advance,

Girish

Answers (1)

Giri
Giri on 1 Jun 2018
Edited: Giri on 1 Jun 2018
I happed to find the solution myself on this. Apparently the only thing that i had to do was
a) Get the required "Profile" node object
b) Seperate out the "Lanes" and "LaneBorders" into two seperate collections
c) Insert each "Lane" between the two required "LaneBorders" using the method "node.insertBefore(newNode,existingNode)" as seen in the code below.
profilesNodeCol = docNode.getElementsByTagName('Profiles'); %Getting all the "Profiles" nodes
for k= 0: profilesNodeCol.getLength-1
profilesK = profilesNodeCol.item(k); %Getting the kth profile
for iCount=0:profilesK.getLength
LBcol = profilesK.item(iCount).getElementsByTagName('LaneBorder'); %Creating a LaneBorder collection
laneCol = profilesK.item(iCount).getElementsByTagName('Lane'); %Creating a Lane collection
for j=0: laneCol.getLength-1
try
profilesK.item(iCount).insertBefore(laneCol.item(j),LBcol.item(j+1)); %Inserting the required Lane between the two required LaneBorders
catch ME
error('Error in function %s() at line %d.\n\nError Message:\n%s', ...
ME.stack(1).name, ME.stack(1).line, ME.message);
end
end
end
end
It uses a nesting of 3 for loops. Which is a kind of NO-NO but it acheives the funcionality. If anyone could suggest a better and optimal way, the tip would be really apreciated.
thanks in advance.
Regards, Giri

Categories

Find more on Image Processing Toolbox in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!