我正在看到我正在维护的Flex应用程序中发生了一些非常奇怪的事情。
我一直在浏览删除对trace()的所有调用,并将其替换为对日志框架的调用(使用内置的mx.logging内容)。在这样做之后,一些XML解析代码突然破了,我不能为我的生活找出原因。
这是代码:
private var loader:URLLoader; // created elsewhere
private function handleComplete(event:Event):void {
default xml namespace = com;
xml = XML(loader.data);
var response:XML = new XML(xml..raniResponse);
//now handles a null response object
if(xml && response.children().length() > 0) {
LOG.debug("Got response.");
var cityXML:XML = new XML(xml..city);
var stateXML:XML = new XML(xml..stateProv);
/* Some extra processing is done here */
}
}
使用这样的代码,使用LOG.debug()调用,我得到了关于cityXML定义的以下错误:
TypeError: Error #1088: The markup in the document following the root element must be well-formed.
如果我注释掉LOG.debug()调用它可以正常工作。
我认为我创建的自定义日志目标可能有些奇怪,所以我删除了它。目前,唯一使用的目标是内置跟踪目标。
有谁知道发生了什么事?为什么日志记录调用会破坏XML解析?我想不出任何会破坏它的事情。
编辑:
我做了一些更多的测试,它只是变得更加怪异。
我根据David的注释更改了代码,使用xml..city [0]代替新XML(xml..city)进行两项分配。这导致异常稍后发生(在某些代码中未显示它引用cityXML的情况)。所以我试着在调试器中单步执行并注意到一些奇怪的事情。
cityXML被设置为null,而stateXML正在获得正确的值。查看调试器中的xml对象显示了所有正确的数据,因此应该没问题。作为随机测试,我重新安排了代码,以便首先加载stateXML。这样做之后,stateXML为null,而cityXML是正确的。
因此,在日志失败后立即发生任何分配,但在此之后发生的任何事情都可以正常工作。
这是正在解析的(有点消毒的)XML:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<com:MyCompanyRANIv.01 xmlns:com="com:myc:rani:1:0:message" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<com:raniResponse>
<com:telephonyInfo>
<com:countryCode>1</com:countryCode>
<com:telephoneNumber>14121234567</com:telephoneNumber>
</com:telephonyInfo>
<com:geoInfo>
<com:coordinates>
<com:latLon>
<com:lat>40.49</com:lat>
<com:lon>-79.92</com:lon>
</com:latLon>
</com:coordinates>
<com:countryInfo>
<com:country>
<com:featureName>United States</com:featureName>
<com:featureTypeDescription>United States of America</com:featureTypeDescription>
<com:featureCode value="US" system="ISO 3166" family="Country Code" systemVer="1-alpha-2" />
</com:country>
</com:countryInfo>
<com:stateProvInfo>
<com:stateProv>
<com:featureName>PENNSYLVANIA</com:featureName>
<com:featureTypeDescription xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
<com:featureCode family="US State Code" system="FIPS State Alpha Code" systemVer="" value="PA" />
</com:stateProv>
</com:stateProvInfo>
<com:regionInfo>
<com:region>
<com:featureName xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
<com:featureTypeDescription xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
<com:featureCode family="" system="" systemVer="" value="" />
</com:region>
</com:regionInfo>
<com:countyParishInfo>
<com:countyParish>
<com:featureName>ALLEGHENY</com:featureName>
<com:featureTypeDescription xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
<com:featureCode family="" system="" systemVer="" value="" />
</com:countyParish>
</com:countyParishInfo>
<com:cityInfo>
<com:city>
<com:featureName>PITTSBURGH</com:featureName>
<com:featureTypeDescription xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
<com:featureCode family="" system="" systemVer="" value="" />
</com:city>
</com:cityInfo>
<com:buildingInfo>
<com:building>
<com:featureName xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
<com:featureTypeDescription xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</com:building>
</com:buildingInfo>
<com:streetAddress address="" />
</com:geoInfo>
<com:services host="false" wireless="false" other="false" />
</com:raniResponse>
<com:raniRequest>
<com:fullyQualifiedTelephoneNumber>14121234567</com:fullyQualifiedTelephoneNumber>
</com:raniRequest>
</com:MyCompanyRANIv.01>
</soapenv:Body>
</soapenv:Envelope>
答案 0 :(得分:1)
这是一个艰难的。我从来没有使用过日志类,所以我不确定问题的那一部分,但是像你一样将XMLList转换为XML:
var cityXML:XML = new XML(xml..city);
仅当XMLList包含单个项目时才有效,否则您会收到引用的警告。请改为使用以下表格:
var cityXML:XML = xml..city[0];
这适用于空列表以及包含许多项目的列表。您还可以检查xml..city.length()
的子项数,如果不是,则记录警告消息。这可能有助于找出确切的问题。
如何通过添加或删除日志记录调用来实现这一点,但是,打败了我。
(在一个有点相关的说明中,我注意到声明和为switch语句的case
块中的XML变量赋值不会按预期工作,即赋值是简单地忽略了,并且变量不会被分配一个值。在两行中断行有帮助。这对我来说似乎也是一个错误,所以在AS3中编译XML相关代码可能并不是一切都正确。)
答案 1 :(得分:1)
将此作为答案而不是编辑发布,因为它包含一些解决方法。
我做了一些测试。这是第一个相关的代码:
LOG.debug("Got response:");
var cityXML:XML = xml..city[0];
var stateXML:XML = xml..stateProv[0];
使用调试器,cityXML被赋值为null,而stateXML获得正确的值。
接下来,我尝试了这个:
LOG.debug("Got response:");
trace("foobar");
var cityXML:XML = xml..city[0];
var stateXML:XML = xml..stateProv[0];
有效! (为什么?!)。 cityXML和stateXML都得到了正确的值。
对此不满意,我尝试了另一项测试。我想也许我只需要在日志和第一个任务之间进行一些其他操作(不知道为什么,但只是在这里进行实验)。所以我尝试了这个:
LOG.debug("Got response:");
var someDumbVariable:Number = 42;
var cityXML:XML = xml..city[0];
var stateXML:XML = xml..stateProv[0];
这不起作用。所以,还有一个测试:
LOG.debug("Got response:");
var cityXML:XML = xml..city[0];
cityXML = xml..city[0];
var stateXML:XML = xml..stateProv[0];
这很有效!当使用调试器单步执行时,第一个赋值以cityXML设置为null结束。但是,第二次赋值给出了正确的值。 (我试过简单地将cityXML行拆分为一行上的声明和另一行上的赋值,但这并未改变行为.2分配似乎是必要的。)
另一种解决方法:
LOG.debug("Got response:");
if(xml.length() == 0) { return; }
var cityXML:XML = xml..city[0];
var stateXML:XML = xml..stateProv[0];
我仍然不知道为什么日志会导致这些事情发生,但似乎要么抛出一条迹线,要么两次尝试分配都会解决问题。我将继续调查,看看我是否可以找出根本原因,但至少我现在有一些解决方法,不涉及删除日志记录。
答案 2 :(得分:0)
嗯。这看起来与我提到的问题非常相似。试试这个:将XML变量声明移到函数的头部:
private function handleComplete(event:Event):void {
var cityXML:XML;
var stateXML:XML;
default xml namespace = com;
xml = XML(loader.data);
var response:XML = new XML(xml..raniResponse);
//now handles a null response object
if(xml && response.children().length() > 0) {
LOG.debug("Got response.");
cityXML = new XML(xml..city);
stateXML = new XML(xml..stateProv);
/* Some extra processing is done here */
}
}
(作为一个单独的答案发布,因为它与前一个答案有很大不同。)