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

Parsing XML with Namespaces

Participant ,
May 15, 2023 May 15, 2023

Copy link to clipboard

Copied

I am trying to use javascript to read an XML file with a custom namespace and feed the contents of several nodes into a series of javascriopt variables.

I have gone through numerous posts in this forum and others (see list below), but have not found an answer that works, doesn't contain a reference link to as dead url, or that I can understand (I am pretty new to js).

 

That said, I am clearly not the first to struggle with this issue.

 

Some of the specific posts I have looked at include:

 

So far, I have not been able to get anything to work!

 

The top of my XML looks like this:

 

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="../CO-Medicare_Combined-Structure.xsd"?>
<!DOCTYPE Root [
  <!ENTITY path "file:///C:/Users/O146962/OneDrive - Kaiser Permanente/Desktop/Indesign Automation POC/Assets/Icons/">
]>
<Root xmlns="kpPDCommon" xmlns:kpdc="kpPDCommon">
  <region kpdc:regionCD="CO">CO</region>
  <lob kpdc:lobCD="MCAR">Medicare</lob>
  <serviceArea>Denver Boulder</serviceArea>
  <planName>Senior Advantage Medicare Medicaid</planName>

 

I am trying to get the contents of "region", "lob", "serviceArea", and "planName" and use that to popluate js variables. However, even just trying to check to see if the file contains "Root" comes back as "Undefined"!

Here is my current javascript&colon;

 

#include "glue code.jsx";

var mainFolder = Folder.desktop + "/Indesign Automation POC";
var templateFolder = mainFolder + "/Template Files - CO";
var outputFolder = mainFolder + "/ID_ScriptOutput";

var dataPath = mainFolder + "/Data/CO_DNB-XML_TEST_SPLIT";
//var file = File(dataPath + "/CO_DNB_Details.xml");
var file = dataPath + '/CO_DNB_Providers_Test_1.xml';

var nskpdc = new Namespace ("kpdc", "kpPDCommon");


var xmlFile = new XML(file);
//xmlFile.addNamespace(nskpdc);
//var nspc = xmlFile.contains("kpdc:Root");


var nspc = xmlFile.contains("Root");

var RGN = xmlFile.elements("region")[0];
var LOB = xmlFile.elements("lob")[0];
var SVCA = xmlFile.elements("serviceArea")[0];
var SVCA_PN = xmlFile.elements("planName")[0];

alert(nspc)
//alert('RGN: ' + RGN + ', LOB: ' + LOB + ', SVCA: ' + SVCA + ', Plan: ' + SVCA_PN);

 

 

I have tried declaring file as a File. I have tried using XML(file.read()). I have tried declaring my namespace. However I am obviously not doing any of this correctly or it should work. 😅

 

Appreciate any help!

 

TOPICS
How to , Scripting , SDK

Views

709

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

People's Champ , May 15, 2023 May 15, 2023
var f = File (Folder.desktop+"/test.xml");
f.encoding ="UTF-8";
f.open("r");
var x = XML(f.read());
f.close();
alert(x.xpath("//kpdc:serviceArea"));

Votes

Translate

Translate
People's Champ ,
May 15, 2023 May 15, 2023

Copy link to clipboard

Copied

var f = File (Folder.desktop+"/test.xml");
f.encoding ="UTF-8";
f.open("r");
var x = XML(f.read());
f.close();
alert(x.xpath("//kpdc:serviceArea"));

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
Participant ,
May 15, 2023 May 15, 2023

Copy link to clipboard

Copied

@Loic.Aigon That worked! What a simple solution for something I had som much trouble with. For my edification, what is the "r" for under "open"?

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
People's Champ ,
May 16, 2023 May 16, 2023

Copy link to clipboard

Copied

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
Participant ,
May 16, 2023 May 16, 2023

Copy link to clipboard

Copied

Thank you!

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
People's Champ ,
May 16, 2023 May 16, 2023

Copy link to clipboard

Copied

Something worth mentioning is that as it's E4X related, note that 

x.xpath("//kpdc:serviceArea")

May not return a String object but XML object. 

What I mean here is that if you run a method to the String Object Prototype right away, it may fail.

So you may need to check node type and if xml, call XML method text() to get the String out of the object.

It's likely ExtendScript (as Javascript by nature) will force conversion from type xml to type String but just don't presume using XPath on XML object will return a string even if it looks so.

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
Participant ,
May 16, 2023 May 16, 2023

Copy link to clipboard

Copied

Good to know! Much appreciated!

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
Participant ,
May 18, 2023 May 18, 2023

Copy link to clipboard

Copied

@Loic.Aigon How would I adjust this if I wanted to load a set of sub-elements into an array?

<saCounties>
        <county>Adams</county>
        <county>Arapahoe</county>
        <county>Boulder</county>
        <county>Broomfield</county>
        <county>Clear Creek</county>
        <county>Denver</county>
        <county>Douglas</county>
        <county>Elbert</county>
        <county>Gilpin</county>
        <county>Jefferson</county>
        <county>Park</county>
    </saCounties>

I want to create an arrary where each "county" element is an item in the array.

let counties = []

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
People's Champ ,
May 18, 2023 May 18, 2023

Copy link to clipboard

Copied

Well, you can use this expression (to be adjusted with namespaces if any)

var x = <saCounties>
        <county>Adams</county>
        <county>Arapahoe</county>
        <county>Boulder</county>
        <county>Broomfield</county>
        <county>Clear Creek</county>
        <county>Denver</county>
        <county>Douglas</county>
        <county>Elbert</county>
        <county>Gilpin</county>
        <county>Jefferson</county>
        <county>Park</county>
    </saCounties>

var counties = x..county //or x.xpath("/saCounties/county";
//BEWARE counties is NOT a js ARRAY but a XMLList object that can be looped through as arrays but don't get the same methods.
var n = counties.length;
var arrCounties = [];
while(n--) arrCounties[n] = counties[n].text(); //getting string value of node and push it into js array
alert("Counties are:\r"+arrCounties.join(", "));

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
Participant ,
May 18, 2023 May 18, 2023

Copy link to clipboard

Copied

@Loic.Aigon  Tried the folowing (and several variations), but no luck so far. 

 

 

 

const xmlFiles = dataFolder.getFiles("*DirProp.xml");
var f = File(xmlFiles[0]);


f.encoding ="UTF-8";
f.open("r");
var x = XML(f.read());
f.close();

//SAC stands for "Service Area Counties"
const SAC = x.xpath("//kpdc:county");
//BEWARE counties is NOT a js ARRAY but a XMLList object that can be looped through as arrays but don't get the same methods.
alert(SAC)
var n = SAC.length;
var arrCounties = [];
while(n--) arrCounties[n] = SAC[n].text(); //getting string value of node and push it into js array
alert("Counties are:\r"+arrCounties.join(", "));

 

 

 

 

The script runs and the following is returned for SAC:

BenRossKP_0-1684431067703.png

But nothing is returned for:

 

 

 

alert("Counties are:\r"+arrCounties.join(", "));

 

 

 

I just get:

BenRossKP_1-1684431119888.png

 

 

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
People's Champ ,
May 18, 2023 May 18, 2023

Copy link to clipboard

Copied

My bad, length should be length() when used on XMLList Objects:

 

var f = File (Folder.desktop+"/test.xml");
f.encoding ="UTF-8";
f.open("r");
var x = XML(f.read());
f.close();
var counties = x.xpath("//kpdc:county");
var n = counties.length();
var arrCounties = [];
while(n--){
    arrCounties[n] = counties[n].text();
}

alert("Counties are:\r"+arrCounties.join(", "));

 

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
Participant ,
May 18, 2023 May 18, 2023

Copy link to clipboard

Copied

That worked! Thanks @Loic.Aigon 

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
Participant ,
May 31, 2023 May 31, 2023

Copy link to clipboard

Copied

LATEST

@Loic.Aigon If I needed to create lists from an XML node's child elements, how would I need to adjust your script?

For the following structure:

 <serviceAreaSnippets>
        <svca_db>
            <db_s1><![CDATA[You can go to all the providers on this list, but your costs for some providers may be less for those who offer preferred cost-sharing. We have noted these providers in the listing as “Preferred cost-sharing providers” to distinguish them from other providers in our network that offer standard cost-sharing. Please refer to the Evidence of Coverage for more information.]]></db_s1>
        </svca_db>
        <svca_nco>
            <nco_s1><![CDATA[You can go to all the providers on this list, but your costs for some providers may be less for those who offer preferred cost-sharing. We have noted these providers in the listing as “Preferred cost-sharing providers” to distinguish them from other providers in our network that offer standard cost-sharing. Please refer to the Evidence of Coverage for more information.]]></nco_s1>
            <nco_s1><![CDATA[You can go to all the providers on this list, but your costs for some providers may be less for those who offer preferred cost-sharing. We have noted these providers in the listing as “Preferred cost-sharing providers” to distinguish them from other providers in our network that offer standard cost-sharing. Please refer to the Evidence of Coverage for more information.]]></nco_s1>
        </svca_nco>
        <scva_soco>
            <soco_s1><![CDATA[You can go to all the providers on this list, but your costs for some providers may be less for those who offer preferred cost-sharing. We have noted these providers in the listing as “Preferred cost-sharing providers” to distinguish them from other providers in our network that offer standard cost-sharing. Please refer to the Evidence of Coverage for more information.]]></soco_s1>
            <soco_s2><![CDATA[Senior Advantage Medicare Medicaid Pueblo (HMO D-SNP) plan members: You may only see PCPs who are located in our Kaiser Permanente Medical Offices. Please refer to the listing of these available network providers on pages <8 and 9> of this Provider Directory.]]></soco_s2>
            <soco_s3><![CDATA[Senior Advantage Core, Enhanced and Employer Group (HMO) and (HMO-POS) plan members: You may see any PCP in our network. Please refer to the listing of these available network providers on pages <10 – 51> of this Provider Directory.]]></soco_s3>
            <soco_s4><![CDATA[Senior Advantage Medicare Medicaid Pueblo (HMO D-SNP) plan members: You may only see primary care providers who are located in our Kaiser Permanente Medical Offices. Please refer to the listing of these available network providers on pages <8 and 9> of this Provider Directory.]]></soco_s4>
            <soco_s5><![CDATA[Senior Advantage Core, Enhanced and Employer Group (HMO) and (HMO-POS) plan members: You may see any primary care provider in our network. Please refer to the listing of these available network providers on <pages 10 – 51> of this Provider Directory.]]></soco_s5>
            <soco_s6><![CDATA[All Southern Colorado Senior Advantage Core, Enhanced and Employer Group (HMO) and (HMO-POS) plan members may see any specialty care provider in our network. Please refer to the listing of these available specialty care network providers beginning on page <52> of this Provider Directory.]]></soco_s6>
        </scva_soco>
    </serviceAreaSnippets>

I need to create a separate are for each child of serviceAreaSnippets. So, separate arrays for svca_db, svca_noco, and svca_soco, where each array contains that node's children.

The result would be three arrays:

svca_db [ db_s1's content ]

svca_noco [nco_s1's content, nco_s2's content]

svca_soco [soco_s1's content, ... soco_s6's content]

 

Any idea how to do that?

 

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