如何在FLEX中将XMLList转换为XML [英] How to convert XMLList to XML in FLEX

查看:172
本文介绍了如何在FLEX中将XMLList转换为XML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经提到了下面这个链接,但找不到解决方案。

Actionscript 3 - 如何将XMLList转换为XML?



My xml变量如下所示:

pre prerivate $ checkXml:XML = new XML(
< >
< item name =cat 2>
< item name =All/>
< item name =item 1/>
< item name =item 2/>
< / item>
< item name =cat 2>
< item name = />
< item name =item 3/>
< item name =item 4/>
< item name =item 5/> ;
< item name =item 5/>
< / item>
< item name =cat 3>
< item name = All 33/>
< item name =item 34/>
< item name =item 44/>
< /项目>
< / universe>);

我使用一个过滤函数去除上面xml中的重复值:

  private function filter(xmlSample:XML):XMLList 
{
var seen:Object = {};
return xmlSample .. @ name。(!seen [valueOf()]&&(seen [valueOf()] = true));
}

返回XMLList数据。当我使用这个来获取XML格式为:

  var thisXml:XMLList = filter(checkXml); 
Alert.show(thisXml.toXMLString());

我没有得到XML格式的输出,我是这样得到的:

  cat 2 
全部
项目1
项目2
项目3
项目4
项目5
猫3
全部33
项目34
项目44

如何在Flex中获得与XML变量checkXml相同的XML格式,这样我就可以保留所有父节点和子节点,因此可以重复获取删除。

解决方案

以下是一个快速建议:

  function clean(xml:XML):XML {
var paths:Dictionary = new Dictionary(true); //记录路径
var result = new XML(< + xml.localName()+/>); //为每个新的xml
(var child:XML in xml。*){//遍历第一级
var path:String = child.parent()。localName()+/+ child.localName()+@+ child。@ name; //获取路径ike)
if(!paths [path]){//如果是新节点
paths [path] = child; //将其存储在字典中
result.appendChild(child。 copy()); //将其添加到结果
} else {//复制子元素
for each(var clone:XML in child。*)//检查重复项,否则插入注意这不会合并子节点:(
if(result [child.localName()] [0]。*。(@ name == clone。@ name).length()== 0)result [child .localName()] [0] .appendChild(克隆);
}
}
trace(result.toXMLString());
返回结果;





$ b

使用基本的xml你可以完成这项工作,但它不是非常灵活。
它应该合并子节点的重复,也许应该递归,但我没有时间atm。

更新:
我有两个版本给你。一个进入子节点的级别:

pre $ 函数clean(xml:XML):XML {
var path :Dictionary = new Dictionary(true); //跟踪
var result = new XML(<+ xml.localName()+/>);
(var child:XML in XML。*){
var path:String = child.parent()。localName()+/+ child.localName()+@+孩子@名。
if(!paths [path]){
paths [path] = child;
result.appendChild(child.copy());
} else
for each(var clone:child in child。*)
if(result [child.localName()] [0]。*。(@ name == clone。@ name).length()== 0)result [child.localName()] [0] .appendChild(clone);
else result [child.localName()] [0]。*。(@ name == clone。@ name)[0] .appendChild(clone。*);
}
返回结果;





$ b

这样的xml:

  var data:XML =< universe> 
< item name =cat 2>
< item name =All>
< item name =item child 1/>
< item name =item child 3>
< item name =item grandchild 1/>
< / item>
< / item>
< item name =item 1>
< item name =item child 1/>
< / item>
< item name =item 2/>
< / item>
< item name =cat 2>
< item name =All>
< item name =item child 2/>
< item name =item child 3>
< item name =item grandchild 2/>
< / item>
< / item>
< item name =item 3/>
< item name =item 4/>
< item name =item 5/>
< item name =item 5/>
< / item>
< item name =cat 3>
< item name =All 33/>
< item name =item 34/>
< item name =item 44/>
< / item>
< / universe>;

会产生如下输出:

 <宇宙> 
< item name =cat 2>
< item name =All>
< item name =item child 1/>
< item name =item child 3>
< item name =item grandchild 1/>
< / item>
< item name =item child 2/>
< item name =item child 3>
< item name =item grandchild 2/>
< / item>
< / item>
< item name =item 1>
< item name =item child 1/>
< / item>
< item name =item 2/>
< item name =item 3/>
< item name =item 4/>
< item name =item 5/>
< / item>
< item name =cat 3>
< item name =All 33/>
< item name =item 34/>
< item name =item 44/>
< / item>
< / universe>

请注意,根节点中的属性会丢失。
可能最好的选择仍然是使用递归,就像这样:
$ b $ $ $ $ $ $ $ $ $ $ $ $> $函数cleanNodes(nodes:XMLList):XML {
var parent:XML = nodes.parent();
var result:XML = new XML(<+ parent.localName()+/>); //复制父节点名称
(var a:属性())结果['@'+ a.name()] = parent.attribute(a.name()); //和属性
//合并重复的一个层次
var found: Dictionary = new Dictionary(true);每个
(var child:节点中的XML){
var name:String = child。@ name;
if(!found [name]){
found [name] = child;
result.appendChild(child);
} else {//合并
找到[name] .appendChild(child。*);

$ b //递归
(var kid:结果中的XML *){//对于每个子节点
if(kid。*。如果它有孩子
var clean:XML = cleanNodes(kid。*); //获取每个子节点的干净副本
删除结果* [kid .childIndex()]; //删除原来的
result.appendChild(clean); //添加清理的(替换)
}
}
返回结果;
}

我不确定这是否是最干净/最优雅的解决方案,但它的工作原理:

  trace(cleanNodes(data。*)); 

产生:

 <宇宙> 
< item name =cat 2>
< item name =item 2/>
< item name =item 3/>
< item name =item 4/>
< item name =item 5/>
< item name =All>
< item name =item child 1/>
< item name =item child 2/>
< item name =item child 3>
< item name =item grandchild 1/>
< item name =item grandchild 2/>
< / item>
< / item>
< item name =item 1>
< item name =item child 1/>
< / item>
< / item>
< item name =cat 3>
< item name =All 33/>
< item name =item 34/>
< item name =item 44/>
< / item>
< / universe>

具有相同名称的节点被递归折叠(如All和item child 3) ,但不幸的是节点排序的方式有点。

I had already referred this following link but could not find the solution for my scenario.

Actionscript 3 - How can i convert from XMLList to XML?

My xml variable is as follows:

private var checkXml:XML = new XML(
<universe>
<item name="cat 2">
     <item name = "All"/>
     <item name = "item 1"/>
     <item name = "item 2"/>
  </item>
  <item name="cat 2">
     <item name = "All"/>
     <item name = "item 3"/>
     <item name = "item 4"/>
     <item name = "item 5"/>
     <item name = "item 5"/>
  </item>
  <item name="cat 3">
     <item name = "All 33"/>
     <item name = "item 34"/>
     <item name = "item 44"/>
  </item>
</universe>);

I use a filter function to remove the duplicate values in above xml as:

private function filter(xmlSample:XML):XMLList 
{
     var seen:Object={};
     return xmlSample..@name.(!seen[valueOf()]&&(seen[valueOf()]=true));
}

which returns XMLList data.When I use this to get an XML format as:

var thisXml:XMLList = filter(checkXml);
Alert.show(thisXml.toXMLString());

I do not get the output in XML format;I get it this way.:

     cat 2
     All
     item 1
     item 2
     item 3
     item 4
     item 5
     cat 3
     All 33
     item 34
     item 44

How to get the same in XML format in Flex like that of my XML variable "checkXml".,so that I can retain all the parent nodes and child nodes as it is thereby the duplicates getting removed.

解决方案

Here's a quick suggetion:

function clean(xml:XML):XML{
    var paths:Dictionary = new Dictionary(true);//keep track of paths
    var result = new XML("<"+xml.localName()+" />");//make new xml
    for each(var child:XML in xml.*){//travers 1st level
        var path:String = child.parent().localName()+"/"+child.localName()+"@"+child.@name;//get a path (I formatted it like)
        if(!paths[path]) {//if it's a new node
            paths[path] = child;//store it in the dictionary
            result.appendChild(child.copy());//add it to the result
        }else {//otherwise copy children
            for each(var clone:XML in child.*)//check for duplicates, otherwise insert, NOTE this does not merge child nodes yet :(
                if(result[child.localName()][0].*.(@name == clone.@name).length() == 0) result[child.localName()][0].appendChild(clone);
        }
    }
    trace(result.toXMLString());
    return result;
}

With the basic xml you have it does the job, but it's not very flexible. It should merge child nodes for duplicates and perhaps should be recursive, but I've got no time atm.

Update: I've got two more versions for you. One that goes into the child nodes a level:

function clean(xml:XML):XML{
    var paths:Dictionary = new Dictionary(true);//keep track of 
    var result = new XML("<"+xml.localName()+" />");
    for each(var child:XML in xml.*){
        var path:String = child.parent().localName()+"/"+child.localName()+"@"+child.@name;
        if(!paths[path]) {
            paths[path] = child;
            result.appendChild(child.copy());
        }else
            for each(var clone:XML in child.*)
                if(result[child.localName()][0].*.(@name == clone.@name).length() == 0) result[child.localName()][0].appendChild(clone);
                else result[child.localName()][0].*.(@name == clone.@name)[0].appendChild(clone.*);
    }
    return result;
}

so an xml like this:

var data:XML = <universe>
<item name="cat 2">
     <item name = "All">
        <item name="item child 1" />
        <item name="item child 3">
            <item name="item grandchild 1" />
        </item>
     </item>
     <item name = "item 1">
        <item name = "item child 1" />
     </item>
     <item name = "item 2"/>
  </item>
  <item name="cat 2">
     <item name = "All">
        <item name="item child 2" />
        <item name="item child 3">
            <item name="item grandchild 2" />
        </item>
     </item>
     <item name = "item 3"/>
     <item name = "item 4"/>
     <item name = "item 5"/>
     <item name = "item 5"/>
  </item>
  <item name="cat 3">
     <item name = "All 33"/>
     <item name = "item 34"/>
     <item name = "item 44"/>
  </item>
</universe>;

produces an output like this:

<universe>
  <item name="cat 2">
    <item name="All">
      <item name="item child 1"/>
      <item name="item child 3">
        <item name="item grandchild 1"/>
      </item>
      <item name="item child 2"/>
      <item name="item child 3">
        <item name="item grandchild 2"/>
      </item>
    </item>
    <item name="item 1">
      <item name="item child 1"/>
    </item>
    <item name="item 2"/>
    <item name="item 3"/>
    <item name="item 4"/>
    <item name="item 5"/>
  </item>
  <item name="cat 3">
    <item name="All 33"/>
    <item name="item 34"/>
    <item name="item 44"/>
  </item>
</universe>

Note that attributes in the root node are lost if any. Probably the best option is still to use recursion, like so:

function cleanNodes(nodes:XMLList):XML{
    var parent:XML = nodes.parent();
    var result:XML = new XML("<"+parent.localName()+" />");//copy parent node name
    for each(var a:XML in parent.attributes()) result['@'+a.name()] = parent.attribute(a.name());//and attributes
    //merge duplicates at one level
    var found:Dictionary = new Dictionary(true);
    for each(var child:XML in nodes){
        var name:String = child.@name;
        if(!found[name]) {
            found[name] = child;
            result.appendChild(child);
        }else{//merge
            found[name].appendChild(child.*);
        }
    }
    //recurse
    for each(var kid:XML in result.*){//for each child node
        if(kid.*.length() > 0){//if it has children
            var clean:XML = cleanNodes(kid.*);//get a clean copy of each child node
            delete result.*[kid.childIndex()];//remove the original
            result.appendChild(clean);        //add the cleaned one (replace)
        }
    }
    return result;  
}

I'm not sure if this is the cleanest/most elegant solution, but it works:

trace(cleanNodes(data.*));

produces:

<universe>
  <item name="cat 2">
    <item name="item 2"/>
    <item name="item 3"/>
    <item name="item 4"/>
    <item name="item 5"/>
    <item name="All">
      <item name="item child 1"/>
      <item name="item child 2"/>
      <item name="item child 3">
        <item name="item grandchild 1"/>
        <item name="item grandchild 2"/>
      </item>
    </item>
    <item name="item 1">
      <item name="item child 1"/>
    </item>
  </item>
  <item name="cat 3">
    <item name="All 33"/>
    <item name="item 34"/>
    <item name="item 44"/>
  </item>
</universe>

Notice nodes with the same names got collapsed recursively (like "All" and "item child 3"), but unfortunately the node order the way a bit.

这篇关于如何在FLEX中将XMLList转换为XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆