Search code examples
javascriptjqueryxmlchildrenxml-documentation

How to get the direct children of a specified tag in xml using JQuery


Please check the below code. I need to check only the children that are defined inside the parent tag.

If any unexpected child appears in that parent I need to report that as error.

This is my XML File:

<places>
  <Tirunelveli>XXXX</Tirunelveli>//allowed child of places
  <Tiruchendur></Tiruchendur>//allowed child of places
  <Alwar></Alwar>//allowed child of places
  <sweet></sweet>//not allowed child of places and i have to report this tag as error
</places>

I need to check that the <places> parent only has child tags that are allowed. Otherwise I need to add it as an error.

var rd = new FileReader();
rd.onload = function(e){  
var xmlDoc = $.parseXML(this.result);                   
var $xml = $(xmlDoc);
//check allowed child of front tag
check_allowed_direct_child("places", "Tirunelveli,Tiruchendur,Alwar", "RULE_002", "Fail");                  

//Function to check the x tag have only the alowed child y
function check_allowed_direct_child(x,y,rule,error_type)
{
    var child_array = y.split(',');
    var child_count=child_array.length;
    var ischild=""
    var xmlchild="";
    $xml.children(x).each(function()
    {
        ischild="no";
        xmlchild=this.value;
        for(i=0;i<count;i++)
        {
        if(child_array[i]==xmlchild)
        {
            ischild="yes";
        }
        }
        if(ischild=="no")
        {
            //count the total error and warnings
            check_total_error_warning(error_type);
            $("#validation_report").append('<tr class="err"><td><a href="Asset\Rules\Rule.html\#'+rule+'">'+rule+'</td><td><span class="highlight">&#x0003C;'+xmlchild+'&#x0003E;</span> is not allowed inside the <span class="highlight">&#x0003C;'+x+'&#x0003E;</span> element</td><td class="'+classname+'">'+error_type+'</td></tr>');
            }

            });
            }

};rd.readAsText(this.files[i]);

But the children() code is not working. What am I doing wrong?


Solution

  • The way you select the parent node needs correction: use find to locate it, then use children on that result (without argument) to get all the children.

    If the parent node is the root of the XML, then find will not find it, but with addBack you can also include the root node in the match.

    I would also use camelCase for your function names, and use jQuery functions to build dynamic HTML.

    Here is how that could look:

    var $xml = $("<aa><bb></bb><cc></cc><dd></dd><ee></ee></aa>");
    var className = "someClass"
     
    //check allowed child of front tag
    checkChildAllowed($xml, "aa", ["bb","cc","dd"], "RULE_002", "Fail");                   
    
    //Function to check the x tag have only the allowed child y
    function checkChildAllowed($xml, parent, allowedChildren, rule, errorType) {
        // Make sure to first locate the parent correctly:
        var $parent = $xml.find(parent).addBack(parent); 
        // Uppercase tag names as jQuery uses that HTML convention
        allowedChildren = allowedChildren.map(childName => childName.toUpperCase()); 
        $parent.children().each(function () {
            if (allowedChildren.includes(this.nodeName)) return; // tag is OK
            // Include this if that function is defined:
            //check_total_error_warning(error_type); 
            $("#validation_report").append( // Use jQuery functions
                $("<tr>").addClass("err").append(
                    $("<td>").append(
                        $("<a>").attr("href", "Asset\Rules\Rule.html\#"+rule).text(rule)
                    ),
                    $("<td>").append(
                        $("<span>").addClass("highlight")
                                   .text("<"+this.nodeName.toLowerCase()+">"),
                        " is not allowed inside the ",
                        $("<span>").addClass("highlight").text("<"+parent+">"),
                        " element"
                    ),
                    $("<td>").addClass(className).text(errorType)
                )
            );
        });
    }
    table { border-collapse: collapse }
    td { border: 1px solid; padding: 5px }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <table id="validation_report"></table>