【问题标题】:Checking if XML values are in an AS3 array检查 XML 值是否在 AS3 数组中
【发布时间】:2016-02-12 10:56:54
【问题描述】:

我有一些以下格式的 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>

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

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

我想知道如何过滤我的 XML(如上所示)以仅显示在 AS3 数组中存在“flightno”的用户。

我猜它是某种 E4X 查询,但我似乎无法正确理解!

谢谢!

【问题讨论】:

    标签: arrays xml actionscript-3 flash


    【解决方案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 -- 这将为您提供一个 XMLList,其中所有节点都名为“user”
    • usersXML.user.(some condition) -- 这会过滤给定条件的用户节点的 XMLList
    • flightNoArray.indexOf(flightno.toString()) &gt;= 0 -- 这是一个过滤条件
    • flightno.toString() -- 在 flightno child 中得到一个字符串
    • REFERENCE: Traversing XML structures
    • Explanation of the search trick 在上面的注释中。

    更新:在 cmets 中发现,过滤器数组的填充方式也导致了问题。下面的代码演示了更多的 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(),它可以得到一个节点的字符串表示。

    【讨论】:

    • 似乎不起作用,我只是得到“无法解析 XML”
    • 我猜只是flash pro cs6(我正在使用)能够解析多行的内联xml,而以前版本的flash IDE则不能。无论如何,要点在// solution:下面的行中。
    • 我正在使用 cc mate,我想玩一玩。感谢您的帮助。
    • @GazSmith 好的,我已经更新了答案。现在应该可以复制粘贴了。
    • 该死的,我希望我在你看到它之前删除了链接 xD
    猜你喜欢
    • 2015-08-27
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 2016-06-22
    • 2020-08-27
    相关资源
    最近更新 更多