Processing arrays/objects pulled from XML?

Processing arrays/objects pulled from XML?

Sorry if this is long-winded. I'll stick a tldr at the end. 

I don't have any development experience, but at my job I occasionally need to use jQuery to manipulate HMTL pages. I've skated by piecing together bits and pieces from the jQuery documentation/various blogs/StackOverflow. 

Lately I've been trying to actually understand what is happening rather than just blindly copying and pasting until something works -- which is what this question relates to. 

Here is my current project:


Audience

Like 6 people on my team, so I generally don't need to worry about browser compatibility or whatever. 

Use Case

We need to do clean-up work on our documentation. 

Sally goes to a page with a drop-down menu. In the menu is a list of 10 products. She selects one, and a table appears containing product-specific search results. 

She reviews the results, clicks the links provided to go fix the source. If a certain result is a false positive or doesn't need to be fixed, she selects the row with a checkbox and clicks a button. That result no longer appears in future searches.  

Notes

The search is done through the API provided by our SaaS. Results are returned in XML, formatted as an RSS feed. There is a limit to the constraints I can include in the query, so for 3 products I have to apply additional filters on the results. 

What I've Done

  1. $.get requests returns XML page with results.

  2. If necessary, filter the results to remove unwanted results. 

  3. Loop through the XML to pull out the relevant text:
    • * The name of the page
    • * The path to the page (which will later become a link)
    • * The page  or file ID# (which will later be hidden and used as a unique ID to identify pages to ignore)

  4. Pull out relevant values and wrap them in table tags

  5. Append results to an empty table.

  6. Once the table is populated, take everything from column 2 and wrap it in <a> tags to make it a clickable link.



I still have to figure out the whole bit about putting/pulling IDs from a hidden div, but I've got some of the bigger pieces ready. 


First, here is the HTML I have in place:

<table id="resultTable">
<thead>
<tr>
<th> Title </th>
<th> Link </th>
<th> Page ID </th>
</tr>
</thead>
<tbody id="resultRows">
</tbody>
</table>


This is an example of what the XML looks like:

<item>
<title> Installing Product Red </title>
<path> Product/Page/Page/Installing_Product_Red </path>
<author> John Smith </author>
<description> This is about installing Product Red. </description>
<page.id> 12345 <page.id>
</item>


And here is my code to create/format the search results table. 

I currently have 4 different functions -- one general one, and 3 unique ones to represent those products that need additional filtering. 

This is an example of what I do with one of the latter:

  1. //url list
  2. redURL='https://example.com?query=blah';

  3. //4 callbacks in total
  4. var fnListRed = $.Callbacks();

  5. function redTable(data) {
  6.     var $XML = $(data),
  7.         $tbody = $('#resultRows'),
  8.         $trs = []; 
  9.     $XML.find("path:contains(5.6)").parent().remove();
  10.     $XML.find("item").each(function () {
  11.         var $this = $(this),
  12.             item = {
  13.                 title: $this.find("title").text(),
  14.                 path: $this.find("path").text(),
  15.                 id: $this.find("page\\.id").text()
  16.             },
  17.             $tr = $('<tr>');
  18.         $.each(item, function (i, item1) {
  19.             $('<td>').html(item1).appendTo($tr);
  20.         });
  21.         $trs.push($tr);                 
  22.     });
  23.     $tbody.append($trs);
  24. };

  25. fnListRed.add(redTable);

  26. function prepColumns() {
  27.     $('#resultRows tr').each(function () {
  28.         var $col2 = $(this).find("td").slice(1, 2),
  29.             $col2text = $col2.text();
  30.             $col2.wrapInner("<a href='https://example.com/" + $col2text + "' </a>");
  31.     });
  32. };

  33. fnListRed.add(prepColumns);
  34. //there are a few more functions in each callback list, so I hope this isn't as unnecessary as it looks

  35. function displayRedResults (data) {
  36.     var $XML = $(data);
  37.     fnListRed.fire($XML);
  38. };

  39. $(document).ready(function () {

  40. //Drop-down menu
  41. $( '#selectProduct' ).change(function () {
  42.     var str = "";
  43.     $( "#selectProduct option:selected" ).each(function () {
  44.         str += $( this ).val();
  45.     });
  46.     if (str == "red") {
  47.         $.get(redURL, displayRedResults);
  48.     } else if (str == "blue") {
  49.         $.get(blueURL, displayResults);
  50. //etc. etc
  51.     });
  52. });



Actual Question/tl;dr

I feel like while the code works, it's incredibly inefficient. It's not super important (the biggest result sets are only a few hundred items), but for my own personal edification I'd like to understand how to make it better and why everything I've tried isn't working. 

For example, I'm not sure if moving the first "contains" selector (line #11) so that it's nested under the .each() loop would be more efficient? Or is it better as-is, because it reduces how many items the loop has to iterate through? 

Even if it is more efficient, I tried doing that a bunch of ways, but couldn't get it to work(warning -- this is a total mess):


I would really like to do my column wrapping within the redTable function but I can't get it to work at all

I tried doing it in the item variable, e.g.:

  1.             item = {
  2.                 title: $this.find("title").text(),
  3.                 path: $this.find("path").each(function () {
  4.                       var $col2 = $(this).text();
  5.                         $(this).wrap("<a href='https://example.com/" + $col2 + "'</a>")}),
  6.                 id: $this.find("page\\.id").text()
  7.             },

And a few variations where I tried .wrapInner or just chaining it all together or adding a whole new function before the $.each loop. 

I also tried doing it under the nested $.each function, but I couldn't figure out how to extract item.path to manipulate it. I was trying to figure out if it had an index, but it seems like every character string is indexed separately (lines 36 and 37)

Any guidance on how to go about doing that?