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
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
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);
}
}
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);
}
}
}
Copy link to clipboard
Copied
Excellent! Thank you very much.