检查XML值是否在AS3阵列中

时间:2015-11-11 10:54:53

标签: arrays xml actionscript-3 flash

我有以下格式的XML。

 <user uid="0001">
    <FirstName>John</FirstName>
    <LastName>Smith</LastName>
    <ImagePath>images/0001.jpg</ImagePath>
    <flightno>GS1234</flightno>
</user>
<user uid="0002">
    <FirstName>Luke</FirstName>
    <LastName>Dixon</LastName>
    <ImagePath>images/0002.jpg</ImagePath>
    <flightno>TD1234</flightno>
</user>
<user uid="0003">
    <FirstName>Paul</FirstName>
    <LastName>Kerr</LastName>
    <ImagePath>images/0003.jpg</ImagePath>
    <flightno>GS1234</flightno>
</user>

这是一个小样本,其中有几个。

我使用E4x过滤来过滤另一组产生as3数组的XML数据。该阵列包含一些航班号(例如:[GS1234,PB7367,TD1234]。

我想知道我如何过滤我的XML(如上所示),只显示其航班的用户名&#39; AS3阵列中的EXISTS。

我猜测它的某种E4X查询,但我似乎无法做到这一点!

谢谢!

1 个答案:

答案 0 :(得分:1)

// Don't mind me using this trick with inline XML, it's not the point.
// It's here just to make it possible to copy and paste code 
// with multiline XML sample.The actual solution is a one-liner below.
var usersXML:XML = new XML(<x><![CDATA[
<data>
<user uid="0001">
    <FirstName>John</FirstName>
    <LastName>Smith</LastName>
    <ImagePath>images/0001.jpg</ImagePath>
    <flightno>GS1234567</flightno>
</user>
<user uid="0002">
    <FirstName>Luke</FirstName>
    <LastName>Dixon</LastName>
    <ImagePath>images/0002.jpg</ImagePath>
    <flightno>TD1234</flightno>
</user>
<user uid="0003">
    <FirstName>Paul</FirstName>
    <LastName>Kerr</LastName>
    <ImagePath>images/0003.jpg</ImagePath>
    <flightno>GS1234</flightno>
</user>
</data>
]]></x>.toString());

// once again, the way I create sample departingXML 
// is not important, it's just for copying and pasting into IDE.
var departingXML:XML = new XML(<x><![CDATA[
<flights>
    <flight>
        <number>GS1234</number>
        <date>10/11/2015</date>
        <time>1440</time>
    </flight>
    <flight>
        <number>TD1234</number>
        <date>10/11/2015</date>
        <time>1450</time>
    </flight>
</flights>
]]></x>.toString());


// 1. create filter array
var flightNoArray:Array = [];
departingXML.flight.number.(flightNoArray.push(toString()));

trace(flightNoArray); // GS1234,TD1234
trace(typeof(flightNoArray[0])); // string

// 2. filter users:
var list:XMLList = usersXML.user.(flightNoArray.indexOf(flightno.toString()) >= 0);

trace(list); // traces users 0002 and 0003

我不会称之为有效或至少可读。

// Note: this line is somewhat queer and I don't like it,

departingXML.flight.number.(flightNoArray.push(toString()));

// but this is the only way I can now think of to get and array 
// of strings from an XMLList nodes without a loop.
// I would advise to use a readable and simple loop instead.
  • usersXML.user - 这会为您提供一个名为“user”
  • 的所有节点的XMLList
  • usersXML.user.(some condition) - 这会过滤给定条件的用户节点的XMLList
  • flightNoArray.indexOf(flightno.toString()) >= 0 - 这是一个过滤条件
  • flightno.toString() - 在flightno child中找到一个字符串
  • REFERENCE: Traversing XML structures
  • Explanation of the search trick在上面的注释中。

更新:在评论中发现它也是填充过滤器阵列导致问题的方式。下面的代码演示了更多的E4X。

这是过滤器列表的创建方式和实际情况:

// once again, the way I create sample departingXML 
// is just for the sake of copying and pasting, it's not related to solution.
var departingXML:XML = new XML(<x><![CDATA[
<flights>
    <flight>
        <number>GS1234</number>
        <date>10/11/2015</date>
        <time>1440</time>
    </flight>
    <flight>
        <number>TD1234</number>
        <date>10/11/2015</date>
        <time>1450</time>
    </flight>
</flights>
]]></x>.toString());

// the way it was done before
var flightNoArray: Array = []; 
for each(var num: XML in departingXML.flight) { 
    flightNoArray.push(num.number);

    // WARNING! num.number is an XMLList! It s NOT a string.
    // Addressing nodes by name ALWAYS gets you an XMLList, 
    // even if there's only one node with that name
    // Hence, `flightNoArray.indexOf("string")` could not possibly work, 
    // as there are lists inside of the array, not strings.


    // We can check if this is a fact:
    trace(flash.utils.getQualifiedClassName(flightNoArray[flightNoArray.length-1])); 
    // (traces XMLList)

    // Or this way (note toXMLString() method)
    trace(flightNoArray[flightNoArray.length-1].toXMLString()); 
    // (traces <number>GS1234</number>)
} 

trace(flightNoArray); 

trace(flightNoArray);跟踪GS1234,TD1234,因为这是toString()方法适用于xml节点的方式 - 它可以获取文本,即内部文本。这就是为什么有一个特殊的方法toXMLString(),它可以获得节点的字符串表示。