I need to concatenate the LastName
and Initials
and all of that authors affiliations. Is there a better way or faster way to do this? I'm very new to working XML in JavaScript.
This is a portion of an XML string that I get back from an API that I parse in JavaScript:
<AuthorList CompleteYN="Y">
<Author ValidYN="Y">
<LastName>Basree</LastName>
<ForeName>Mustafa M</ForeName>
<Initials>MM</Initials>
<AffiliationInfo>
<Affiliation>The Cancer Center...</Affiliation>
</AffiliationInfo>
</Author>
<Author ValidYN="Y">
<LastName>Shinde</LastName>
<ForeName>Neelam</ForeName>
<Initials>N</Initials>
<AffiliationInfo>
<Affiliation>The Comprehensive..</Affiliation>
</AffiliationInfo>
</Author>
<Author ValidYN="Y">
<LastName>Koivisto</LastName>
<ForeName>Christopher</ForeName>
<Initials>C</Initials>
<AffiliationInfo>
<Affiliation>Hollings ...</Affiliation>
</AffiliationInfo>
<AffiliationInfo>
<Affiliation>Department ...</Affiliation>
</AffiliationInfo>
</Author>
<Author ValidYN="Y">
<LastName>Cuitino</LastName>
<ForeName>Maria</ForeName>
<Initials>M</Initials>
<AffiliationInfo>
<Affiliation>Hollings...</Affiliation>
</AffiliationInfo>
<AffiliationInfo>
<Affiliation>Department ..</Affiliation>
</AffiliationInfo>
</Author>
</AuthorList>
my Code:
let HTMLContent = ""
parser = new DOMParser();
xmlDoc = parser.parseFromString(response.data, "text/xml");
const AuthorsInfo = xmlDoc.querySelectorAll("Author");
AuthorsInfo.forEach(a => {
let affiliations = "";
let AuthorName = "";
for (var i = 0; i < a.children.length; i++) {
let tt = a.children[i].nodeName;
let t = a.children[i].textContent;
if (tt === "AffiliationInfo") {
affiliations += a.children[i].textContent;
affiliations += "<br /><br />";
} else if (tt === "LastName") {
AuthorName = a.children[i].textContent;
} else if (tt === "Initials") {
AuthorName += " " + a.children[i].textContent;
AuthorName += "<br /><br />";
}
}
HTMLContent += AuthorName + " " + affiliations;
});
-
\$\begingroup\$ Can the node loop be improved \$\endgroup\$user1314159– user13141592019年10月08日 13:16:49 +00:00Commented Oct 8, 2019 at 13:16
1 Answer 1
Style
Inconsistent use of line ending semi colon
Undeclared variables
parser
andxmlDoc
Unused code.
let t = a.children[i].textContent;
t
is never used the line should not be therePoor naming
- Capitalisation of variable names. Only if objects to be instanciated via new
token
, if accronim (eg HTML, XML) or if a constant (optional). Examples;AuthorsInfo
should beauthorsInfo
,AuthorName
asauthorName
,xmlDoc
asXMLDoc
. - Non descripttive names,
a
,tt
,t
- Semanticly inacurate names,
AuthorsInfo
eitherauthorNodes
or justauthors
- Capitalisation of variable names. Only if objects to be instanciated via new
Use
for of
loops rather thanfor if
loops if you do not need the index counterUse
for of
loops rather thanArray
iteratorsFunction scoped variables should be declared as
var
and hoisted to the top of the function
Code design
As you have several potential errors in the code (undeclared variables) you should ALWAYS use the directive "use strict"
in your code to ensure these types of syntax problems are caught early in the development process.
Always present your code as a function/s. Presenting code as flat global scoped source string is very poor design practice.
Flat code often ends up performing many tasks that should be separated. Writing functions helps you define task roles under clearly named functions.
The parsing of the XML to HTML is more than one task. I suggest you have two functions parseAuthors
to extract the author details, and authorsToHTML
to create the markup.
Example rewrite
From your code it is unclear as to the nature of the XML. Can authors have no last name, initials, or affiliations. Do authors always have one last name, does the last name always come before the initials. And many more unanswered questions regarding the XML.
The example assumes that the XML given defines the XML.
The example breaks the code into many smaller functions and puts them all together inside a IIF (immediately invoked function). In the real world you would put all the code inside a module.
"use strict";
// As IFF or better as module (No need for use strict if module)
const authors = (() => {
const AUTHORS = "Author";
const AFFILIATION = "AffiliationInfo";
const LAST_NAME = "LastName";
const INITIALS = "Initials";
const SEP = "<br/><br/>";
const nodeTxt = (node, name) => (name ? node.querySelector(name) : node).textContent;
function Author(authorNode) {
const author = {
lastName: nodeTxt(authorNode, LAST_NAME),
initials: nodeTxt(authorNode, INITIALS),
affiliations: []
}
for (const affNode of authorNode.querySelectorAll(AFFILIATION)) {
author.affiliations.push(nodeTxt(affNode));
}
return author;
}
return {
parse(XMLString) {
const authors = [];
const authorNodes = new DOMParser()
.parseFromString(XMLString, "text/xml")
.querySelectorAll("Author");
for (const authorNode of authorNodes) { authors.push(Author(authorNode)) }
return authors;
},
toHTML(authors) {
var markup = "";
for (const author of authors) {
markup += author.lastName + " " + author.initials + SEP;
markup += " " + author.affiliations.join(SEP) + SEP;
}
return markup;
},
};
})();
document.body.innerHTML = authors.toHTML(authors.parse(getXML()));
function getXML() { return `<AuthorList CompleteYN="Y">
<Author ValidYN="Y">
<LastName>Basree</LastName>
<ForeName>Mustafa M</ForeName>
<Initials>MM</Initials>
<AffiliationInfo>
<Affiliation>The Cancer Center...</Affiliation>
</AffiliationInfo>
</Author>
<Author ValidYN="Y">
<LastName>Shinde</LastName>
<ForeName>Neelam</ForeName>
<Initials>N</Initials>
<AffiliationInfo>
<Affiliation>The Comprehensive..</Affiliation>
</AffiliationInfo>
</Author>
<Author ValidYN="Y">
<LastName>Koivisto</LastName>
<ForeName>Christopher</ForeName>
<Initials>C</Initials>
<AffiliationInfo>
<Affiliation>Hollings ...</Affiliation>
</AffiliationInfo>
<AffiliationInfo>
<Affiliation>Department ...</Affiliation>
</AffiliationInfo>
</Author>
<Author ValidYN="Y">
<LastName>Cuitino</LastName>
<ForeName>Maria</ForeName>
<Initials>M</Initials>
<AffiliationInfo>
<Affiliation>Hollings...</Affiliation>
</AffiliationInfo>
<AffiliationInfo>
<Affiliation>Department ..</Affiliation>
</AffiliationInfo>
</Author>
</AuthorList>`
};
-
\$\begingroup\$ Hello, I am a javascript beginner and probably mine is an obvious question: why there is no need to use strict in a module and if there are other cases when not to use strict in javascript code. Thanks in advance. \$\endgroup\$dariosicily– dariosicily2019年10月10日 13:00:22 +00:00Commented Oct 10, 2019 at 13:00
-
\$\begingroup\$ @dariosicily Modules are automatically strict mode and it can not be turned off. There are no good reasons not to use strict mode. For more information developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… \$\endgroup\$Blindman67– Blindman672019年10月10日 16:33:11 +00:00Commented Oct 10, 2019 at 16:33
-
\$\begingroup\$ Fantastic- Thank you. I will include much of your rewrite \$\endgroup\$user1314159– user13141592019年10月10日 18:52:23 +00:00Commented Oct 10, 2019 at 18:52