• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Recursive Algorithm Help

Community Expert ,
Jun 24, 2015 Jun 24, 2015

Copy link to clipboard

Copied

Hi Everyone. I am recursively processing an XML file using ExtendScript. I have a "level" variable so I can keep track of how deep I am in the structure. I want to detect when the level changes in either direction. I am having trouble figuring out how to use a "prevLevel" variable to keep track of the current level so I can see if it has changed. It seems to work when the level increases, but not when it decreases. Any help would be appreciated. Here is my script. It will prompt you for an XML file, which I will also post.

main ();

function main () {

   

    var xmlFile, xml;

   

    // Prompt the user for the XML file.

    xmlFile = File.openDialog ("Please select an xml file:","XML:*xml", false);

    if (xmlFile === null) {

        return; // User cancelled the XML dialog box.

    }

    xml = loadXmlFile (xmlFile);

    if (xml === 0) {

        alert ("XML file could not be loaded.");

        return;

    }

    processElements (xml, 1, 0);

}

function processElements (node, level, prevLevel) {

   

    var nodes = node.elements ();

    var count = nodes.length (), i;

   

    for (i = 0; i < count; i += 1) {

        $.writeln (level + " " + nodes.localName () + " (" + prevLevel + ")");

        prevLevel = level;

        if (nodes.hasComplexContent () === true) {

            processElements (nodes, level + 1, prevLevel);

        }

    }

}

function loadXmlFile (xmlFile) {

   

    var xml = 0;

    // Open, read, and close the XML file.

    xmlFile.open("r");

    try {

        xml = new XML(xmlFile.read());

    } catch (e) {

        xmlFile.close();

        return xml;

    }

    xmlFile.close();

    return xml;

}

<?xml version="1.0" encoding="utf-8"?>

<Boek>

  <CursusTitelblad href="C:\temp\Presentatie\CursusTitelblad-1\PresentGBS-StorOndh-CursusVB.xml" />

  <Inhoud />

  <Hoofdstuk>

    <Titelblad href="C:\temp\Presentatie\Hoofdstuk-1\PresentHfst-SignaalgeversVeld.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-1\PresentInlSignaalgevers.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-1\PresentWat zijn Signaalgevers.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-1\PresentSignaalgevrOpnemer.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-1\PresentType signaalgevers.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-1\PresentType opnemers.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-1\PresentTypen signalen.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-1\PresentSpecificatiesDocumentatie.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-1\PresentMetenSignaalgevers-Signalen.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-1\PresentPlaatsing Signaalgevers.xml" />

    <OpgTheorie href="C:\temp\Presentatie\Hoofdstuk-1\PresentOpgTh-SignaalgeversVeld.xml" />

    <OpgTechTake href="C:\temp\Presentatie\Hoofdstuk-1\PresentOpgvTT-SignVerbindingGBSVeld.xml" />

    <PraktijkOpdracht href="C:\temp\Presentatie\Hoofdstuk-1\PresentPrakOpdr-SignaalgeversVeld.xml" />

  </Hoofdstuk>

  <Hoofdstuk>

    <Titelblad href="C:\temp\Presentatie\Hoofdstuk-2\PresentHfst-UitvoerorganenVeld.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-2\PresentInlUitvoerorganen.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-2\PresentSoortenUitvoerorganen.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-2\PresentTypeStuursignalenUitvoerorganen.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-2\PresentSpecificatiesUitvoerorganen.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-2\PresentMetenSignalenUitvoerorganen.xml" />

    <OpgTheorie href="C:\temp\Presentatie\Hoofdstuk-2\PresentOpgTh-UitvoerorganenVeld.xml" />

    <PraktijkOpdracht href="C:\temp\Presentatie\Hoofdstuk-2\PresentPrakOpdr-UitvoerorganenVeld.xml" />

  </Hoofdstuk>

  <Hoofdstuk>

    <Titelblad href="C:\temp\Presentatie\Hoofdstuk-3\PresentHfst-SignaalverbindingGBS.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-3\PresentInlSignaalverbindGBS-Veld.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-3\PresentSoorten I-O-Modulen.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-3\PresentVerbindingenVeldModulen.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-3\PresentVerbindingenModulenOnderling.xml" />

    <OpgTheorie href="C:\temp\Presentatie\Hoofdstuk-3\PresentOpgTh-SignVerbindingGBSVeld.xml" />

    <PraktijkOpdracht href="C:\temp\Presentatie\Hoofdstuk-3\PresentPrakOpdr-SignVerbindingGBSVeld.xml" />

  </Hoofdstuk>

  <Hoofdstuk>

    <Titelblad href="C:\temp\Presentatie\Hoofdstuk-4\PresentHfst-SignaalverbindingenAansluit.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-4\PresentInlSignaalverbindingen.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-4\PresentGebruikSchemaDocumentatie.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-4\PresentHoofd-Stuurstroomschema.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-4\PresentDocumentatieComponenten.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-4\PresentI-O-LijstenSchema.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-4\PresentKlemmenlijst-Rangeren.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-4\PresentMeten I-O-Signalen.xml" />

    <OpgTheorie href="C:\temp\Presentatie\Hoofdstuk-4\PresentOpgvTh-SignVerbindAansluit.xml" />

    <PraktijkOpdracht href="C:\temp\Presentatie\Hoofdstuk-4\PresentPrakOpdr-SignVerbindAansluit.xml" />

  </Hoofdstuk>

  <Hoofdstuk>

    <Titelblad href="C:\temp\Presentatie\Hoofdstuk-5\PresentHfst-CommVerbindingenGBS.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-5\PresentInlCommVerbingenGBS.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-5\PresentTypeCommVerbindingen.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-5\PresentGateways.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-5\PresentAdresbusGBS-systeem.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-5\PresentDataPackets.xml" />

    <OpgTheorie href="C:\temp\Presentatie\Hoofdstuk-5\PresentOpgTh-CommVerbindingenGBS.xml" />

    <PraktijkOpdracht href="C:\temp\Presentatie\Hoofdstuk-5\PresentPrakOpdr-CommVerbindingenGBS.xml" />

  </Hoofdstuk>

  <Hoofdstuk>

    <Titelblad href="C:\temp\Presentatie\Hoofdstuk-6\PresentHfst-GestructureerdSmido.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-6\PresentInlGestrucStorzGBS.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-6\PresentStoringsmeldingKlachtStoring.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-6\PresentStorzoekenSmido.xml" />

    <Onderwerp href="C:\temp\Presentatie\Hoofdstuk-6\PresentGBS-sysGebruikStorzoek.xml" />

  </Hoofdstuk>

</Boek>

The script will write the results to the JavaScript Console. Here are the results that I am getting. This is pretty much what I want, except when the level goes back, it doesn't properly display the previous level.

1 CursusTitelblad (0)

1 Inhoud (1)

1 Hoofdstuk (1)

2 Titelblad (1)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 OpgTheorie (2)

2 OpgTechTake (2)

2 PraktijkOpdracht (2)

1 Hoofdstuk (1)

2 Titelblad (1)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 OpgTheorie (2)

2 PraktijkOpdracht (2)

1 Hoofdstuk (1)

2 Titelblad (1)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 OpgTheorie (2)

2 PraktijkOpdracht (2)

1 Hoofdstuk (1)

2 Titelblad (1)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 OpgTheorie (2)

2 PraktijkOpdracht (2)

1 Hoofdstuk (1)

2 Titelblad (1)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 OpgTheorie (2)

2 PraktijkOpdracht (2)

1 Hoofdstuk (1)

2 Titelblad (1)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

2 Onderwerp (2)

So, for example, when it jumps back to one of the <Hoofdsuk> elements, I am seeing this:

1 Hoofdstuk (1)

instead of

1 Hoofdstuk (2)

-Rick

TOPICS
Scripting

Views

483

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Explorer , Jun 25, 2015 Jun 25, 2015

Presumably you've expected that prevLevel is handed over "by reference" during recursion, which is true for objects, but not for simple variables.

It should work when you define prevLevel as an object:

function main () { 

     

    var xmlFile, xml; 

     

    // Prompt the user for the XML file. 

    xmlFile = File.openDialog ("Please select an xml file:","XML:*xml", false); 

    if (xmlFile === null) { 

        return; // User cancelled the XML dialog box. 

    } 

 

    xml = loadXmlF

...

Votes

Translate

Translate
Community Expert ,
Jun 24, 2015 Jun 24, 2015

Copy link to clipboard

Copied

Here is a different way of expressing the recursive processElements function, although I am still having the same problem keeping track of the previous level.

function processElements (node, level, prevLevel) {

  

    var nodes, count, i;

  

    $.writeln (level + " " + node.localName () + " (" + prevLevel + ")");

  

    nodes = node.elements ();

    count = nodes.length ();

    if (count > 0) {

        prevLevel = level;

        level += 1;

    }

    for (i = 0; i < count; i += 1) {

        processElements (nodes, level, prevLevel);

    }  

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jun 25, 2015 Jun 25, 2015

Copy link to clipboard

Copied

Presumably you've expected that prevLevel is handed over "by reference" during recursion, which is true for objects, but not for simple variables.

It should work when you define prevLevel as an object:

function main () { 

     

    var xmlFile, xml; 

     

    // Prompt the user for the XML file. 

    xmlFile = File.openDialog ("Please select an xml file:","XML:*xml", false); 

    if (xmlFile === null) { 

        return; // User cancelled the XML dialog box. 

    } 

 

    xml = loadXmlFile (xmlFile); 

    if (xml === 0) { 

        alert ("XML file could not be loaded."); 

        return; 

    } 

   

    var prevLevel = { val : 0 };  // CHANGED

    processElements (xml, 1, prevLevel); 

 

function processElements (node, level, prevLevel) { 

     

    var nodes = node.elements (); 

    var count = nodes.length (), i; 

     

    for (i = 0; i < count; i += 1) { 

        $.writeln (level + " " + nodes.localName () + " (" + prevLevel.val + ")");  // CHANGED

        prevLevel.val = level;    // CHANGED

        if (nodes.hasComplexContent () === true) { 

            processElements (nodes, level + 1, prevLevel); 

        } 

    } 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 25, 2015 Jun 25, 2015

Copy link to clipboard

Copied

LATEST

Excellent! Thank you very much.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines