0

我有一个这样的 xml 文件:(这是动态创建的 xml 文件,类别不是静态的)

<data>
    <step id="1">
        <category id="js"></category>
        <category id="css"></category>
        <category id="xml"></category>
    </step>
    <step id="2">
        <category id="js"></category>
        <category id="css"></category>
        <category id="xml"></category>
        <category id="php"></category>
        <category id="html"></category>
    </step>
    <step id="3">
        <category id="xml"></category>
        <category id="php"></category>
        <category id="html"></category>
    </step>
</data>

我想将 xml 文件转换为 javascript 对象我用 jquery 做

$.get('data.xml', function(xml){
    var oXML = $(xml).find('data'),
        data = {};

    oXML.each(function(){
        var stepID = jQuery(this).attr('id');
        data[stepID] = {};

        jQuery(this).each(function(){
            var categoryID = jQuery(this).attr('id')
            data[stepID][categoryID] = 'is available';

        });
    });
});

结果看起来像这样

obj = {
1: {
    js: 'is available',
    css: 'is available',
    xml: 'is available'
},

2: {
    js: 'is available',
    css: 'is available',
    xml: 'is available',
    php: 'is available',
    html: 'is available'

},

3: {
    xml: 'is available',
    php: 'is available',
    html: 'is available'
}
}

但我希望在所有步骤中都有所有类别。你知道我该怎么做吗?我想要这样的结果对象

obj = {
    1: {
        js: 'is available',
        css: 'is available',
        xml: 'is available',
        php: 'is not available',
        html: 'is not available'
    },

    2: {
        js: 'is available',
        css: 'is available',
        xml: 'is available',
        php: 'is available',
        html: 'is available'

    },

    3: {
        js: 'is not available',
        css: 'is not available',
        xml: 'is available',
        php: 'is available',
        html: 'is available'
    }
}
4

4 回答 4

2

收集所有类别,然后通过数据枚举并设置缺失的类别:

$.get('data.xml', function(xml){
    var oXML = $(xml).find('data'),
        data = {},
        categories = {};

    oXML.each(function(){
        var stepID = jQuery(this).attr('id');
        data[stepID] = {};
        jQuery(this).each(function(){
            var categoryID = jQuery(this).attr('id');
            if (!categories[categoryID]) {
                categories[categoryID] = true;
            }
            data[stepID][categoryID] = 'is available';
        });
    });
    $.each(data, function (key, value) {
        $.each(categories, function (key) {
            if (value[key] === undefined) {
                value[key] = 'is not available';
            }
        });
    });
});
于 2013-01-13T18:47:57.863 回答
1

使用所有属性设置为“不可用”来启动您的对象。

添加后,您不知道自己拥有哪些类别,我建议您这样做

$.get('data.xml', function(xml){
    var oXML = $(xml).find('data'),
        data = {};

    // create a constructor for our object. We'll add the "not available" to the prototype later
    // I create it inside your request because I assume that the process of "remembering"
    // which properties exists should not be global but just for this request
    function DataObject () {};


    oXML.each(function(){
        var stepID = jQuery(this).attr('id');
        data[stepID] = new DataObject; // use an instance of our DataObject

        jQuery(this).each(function(){
            var categoryID = jQuery(this).attr('id')
            data[stepID][categoryID] = 'is available';

            // now add this propertiy to our prototype
            // this will "add" them to all instances of DataObject
            DataObject.prototype[categoryID] = 'is not available';
        });
    });
});

要完全理解这一点,您必须了解原型的概念。每个对象都有一个__proto__属性。如果您访问data[0].html并且它在对象中不可用,则 Javascript 会检查哪些是__proto__对构造函数的引用prototype。因为你'is not available在原型中添加了你的结果data[0].html'is not available

于 2013-01-13T18:52:27.430 回答
1

您可以在构造对象后对其进行迭代以填充缺失的成员:

$.each(data, function (i, ival) {
    var member = ival;
    $.each(data, function (j, jval) {
        if (jval === member) return;
        $.each(jval, function (k, kval) {
            if (typeof (member[k]) === 'undefined') {
                member[k] = 'is not available';
            }
        });
    });
});

您的最终代码将如下所示:

$.get('data.xml', function(xml){
    var oXML = $(xml).find('data'),
        data = {};

    oXML.each(function(){
        var stepID = jQuery(this).attr('id');
        data[stepID] = {};

        jQuery(this).each(function(){
            var categoryID = jQuery(this).attr('id')
            data[stepID][categoryID] = 'is available';
        });
    });

    $.each(data, function (i, ival) {
        var member = ival;
        $.each(data, function (j, jval) {
            if (jval === member) return;
            $.each(jval, function (k, kval) {
                if (typeof (member[k]) === 'undefined') {
                    member[k] = 'is not available';
                }
            });
        });
    });
});
于 2013-01-13T19:01:37.967 回答
0

解析数据时,在 xml 中存储所有可用类别的数组:

然后,一旦所有 xml 被解析,您将拥有所有可用类别的完整数组,循环主对象并查看每个元素是否包含每个类别属性:

var oXML = $(xml).find('step'),
        data = {},
    cats_array=[];

    oXML.each(function(){

        var stepID = jQuery(this).attr('id');      
        data[stepID] = {};
        jQuery(this).find('category').each(function(){                    
            var categoryID = jQuery(this).attr('id');
          /* add category to array if doesn't already exist*/
           if( $.inArray( categoryID, cats_array) ==-1){
           cats_array.push( categoryID);
        }
            data[stepID][categoryID] = 'is available';

        });
    });
/* all categories now in array, loop over main object and if category doesn't exist add it*/
$.each(data, function(){
    for( i=0;i< cats_array.length; i++){
        if( ! this[cats_array[i]] ){
           this[cats_array[i]] ="not available";
        }
     }

})

工作演示:http: //jsfiddle.net/MYXNh/2/

于 2013-01-13T19:01:08.607 回答