patternjavascriptMinor
Build menu from MS Word XML
Viewed 0 times
xmlmenuwordfrombuild
Problem
I've recently assembled some jQuery that allows a user to build out a bulleted list in MS Word with hyperlinks and turn that into a HTML unordered list. Ideas for uses are website menu systems where the user may not have a clue about HTML. You can also extend this with jQuery UI plugins for effects. Looking for edge cases.
/*
The following will read in a bullet list from in a MS Word XML file and turn it into a
unordered list with hyperlinks. Perhaps to use as a menu.
*/
$.ajax({
type: "GET",
async: false,
url: "Menu.xml",
dataType: "xml",
success:function(results){
var currentDepth = 0;
$("#menu").append('');
$(results).find("[nodeName=w:p]").each(function(){
if($(this).find("[nodeName=w:pStyle]").attr('w:val') == 'ListParagraph'){
var liValue = $(this).find("[nodeName=w:t]").text();
var hyper = $(this).find("[nodeName=w:hyperlink]").attr('r:id');
var placeAtDepth = parseInt($(this).find("[nodeName=w:ilvl]").attr('w:val'), 10);
if(placeAtDepth > currentDepth){
$(".menuLvl"+ currentDepth).append('');
}
currentDepth = placeAtDepth;
//Determine if we have an hyperlink
if(hyper != null){
var link = $(results).find('Relationship[Id='+hyper+']').attr('Target');
liValue = ''+ liValue +'';
}
$(".menuLvl"+currentDepth).last().append(''+ liValue +'');
}
});
}
});Solution
Looks fine (maybe some stricter formatting could help readibility, but not an issue), so I'll suggest completely optional improvements that might help spotting important improvements.
As a general principle, try to be ready for bogus values in your input so you can avoid generating nonsense. Being more robust will also make reusing your code for somewhat different tasks easier.
As a general principle, try to be ready for bogus values in your input so you can avoid generating nonsense. Being more robust will also make reusing your code for somewhat different tasks easier.
$.ajax({
/// [...]
success:function(results){
/// [...]
$(results).find("[nodeName=w:p]").each(function(){
if($(this).find("[nodeName=w:pStyle]").attr('w:val') == 'ListParagraph'){
var liValue = $(this).find("[nodeName=w:t]").text();
/// -^ What if the input has an empty value here? Skip?
var hyper = $(this).find("[nodeName=w:hyperlink]").attr('r:id');
var placeAtDepth = parseInt($(this).find("[nodeName=w:ilvl]").attr('w:val'), 10);
/// -^ parseInt can return a NaN, maybe you want to bail out in that case?
/// Should also handle some bogus results for .find.
if(placeAtDepth > currentDepth){
$(".menuLvl"+ currentDepth).append('');
}
currentDepth = placeAtDepth;
//Determine if we have an hyperlink
if(hyper != null){
var link = $(results).find('Relationship[Id='+hyper+']').attr('Target');
/// -^ This can result in an invalid link for broken input. But what if
the input is malicious (JS hrefs)?
liValue = ''+ liValue +'';Code Snippets
$.ajax({
/// [...]
success:function(results){
/// [...]
$(results).find("[nodeName=w:p]").each(function(){
if($(this).find("[nodeName=w:pStyle]").attr('w:val') == 'ListParagraph'){
var liValue = $(this).find("[nodeName=w:t]").text();
/// -^ What if the input has an empty value here? Skip?
var hyper = $(this).find("[nodeName=w:hyperlink]").attr('r:id');
var placeAtDepth = parseInt($(this).find("[nodeName=w:ilvl]").attr('w:val'), 10);
/// -^ parseInt can return a NaN, maybe you want to bail out in that case?
/// Should also handle some bogus results for .find.
if(placeAtDepth > currentDepth){
$(".menuLvl"+ currentDepth).append('<ul class="menuLvl'+ placeAtDepth +'">');
}
currentDepth = placeAtDepth;
//Determine if we have an hyperlink
if(hyper != null){
var link = $(results).find('Relationship[Id='+hyper+']').attr('Target');
/// -^ This can result in an invalid link for broken input. But what if
the input is malicious (JS hrefs)?
liValue = '<a href="'+ link +'">'+ liValue +'</a>';Context
StackExchange Code Review Q#190, answer score: 5
Revisions (0)
No revisions yet.