2

我不禁认为,使 XML 和 XMLList 都无关,因为两者都直接扩展 Object,这是 AS3 核心库中的设计缺陷。当然,让 XML 扩展 XMLList 会是一个更简洁的系统,其中 XML 被认为是只有一个成员的 XMLList?

这也将避免 E4X 查询可能返回 XML 或 XMLList 的非常烦人的做法,这可能会导致转换错误。

那么有什么理由我不认为 XML 和 XMLList 被设计为仅将 Object 作为一种通用类型?

4

4 回答 4

2

似乎根据E4X (p22)的ECMA 规范和XMLList 文档XMLList类确实包含XML类的方法,但仅当有一个成员时。因此,在执行 E4X 查询时,结果应始终存储在XMLList类型的变量中。

之前,由于这些对象的命名,我假设一个XML对象代表一个 XML 元素数据的复杂树,但根据规范(p12),这不是真的,“每个XML类型的值代表一个 XML 元素,属性、注释、处理指令或文本节点”。

应该将XMLList类用作两者中更通用的类型:“ XMLList类型的值表示 XML 文档、XML 片段或 XML 对象的任意集合(例如,查询结果)”

所以这解决了我的转换问题,因为我不应该将 E4X 查询存储为XML类型的变量。我应该只使用XML类来迭代XMLLists和分解 XML 元素。

于 2009-03-08T08:16:43.223 回答
0

所以我对这个问题的简洁回答是,从继承树看来,是的,这两个类(XMLListXML)是不相关的。

但是,通过查看 ECMA 脚本/AS3 文档,它们是相关的,很可能使用 ECMA 脚本/AS3 的原型系统。

当一个XMLList只有一个成员时,它可以被视为一个 XML 节点。我假设 XML 类的方法和字段是由 AVM2 插入到 XMLList 原型中的。

于 2009-03-11T09:08:12.140 回答
0

正如您所注意到的,自动更改的 XML 和 XMLList 类型会变得相当混乱。当聪明的程序员(在这里指向 Adob​​e ..)制作方便的包装器时,就会发生这种事情。

正在发生的是一种“自动类型转换”。它并不止于 XML 类型。考虑这个示例 XML:

<myXml>
    <sound id="0">Boogaloo</sound>
    <sound id="1">Bond theme</sound>
    <sound id="2">2001</sound>
</myXml>

假设我在一个名为myXml. 在以下示例中,E4X 返回一个带有一个项目的 XMLList,我们使用以下命令访问第一个 XML 项目[0]

trace(myXml.sound.(@id == 0)[0] == <sound id="0">Boogaloo</sound>);
// traces true

在这个例子中,我们省略了[0]部分,依赖于 Flash 的自动类型转换。返回的一项将转换为 XML:

trace(myXml.sound.(@id == 0) == <sound id="0">Boogaloo</sound>);
// traces true

但是如果这个匹配的 XML 节点包含一个简单的文本节点,Flash 会自动将该类型进一步转换为字符串:

trace(myXml.sound.(@id == 0) == "Boogaloo");
// traces true

如果文本节点可以解释为数字(ID 为 2 的 XML 节点),Flash 会进一步将其转换为数字!

trace(myXml.sound.(@id == 2) == 2001);
// traces true

哇!

那么,该怎么办呢?

正如您所注意到的,您必须非常小心类型和“方便”的 XML 处理。一个建议的做法是始终使用数组访问运算符来指向 E4X 结果的第一个 XML 项,当您知道您需要单个结果时:

config.users.admin[0].settings[0].email.(@type == "work")[0];

一开始它看起来很奇怪,并且给代码增加了冗长,但好处是你明确地说你正在寻找一个 admin元素、一个 settings元素和一个 emailtype 元素"work"。而且你习惯了它的外观。

另一个提示是始终记住转换为您期望使用的类型。一些例子:

allUsers       = XMLList(config.users);
adminSettings  = XML(config.users.admin[0].settings[0]);
adminWorkEmail = String(config.users.admin[0].settings[0].email.(@type == "work")[0]);
adminBirthYear = int(config.users.admin[0].birthdate[0].@year[0]);
于 2009-05-20T22:58:02.330 回答
0

在 ActionScript 3.0 中,XMLList 是处理 xml 的新方法,因为 XML 类是 AS 2 的东西,所以它被包含以提供向后兼容性。

如果您编写新代码,您现在应该使用 XMLList。

希望这可以帮助

乔恩

于 2009-06-22T14:59:51.420 回答