Ведение журнала, вызывающее сбой анализа XML? - PullRequest
4 голосов
/ 31 января 2009

Я вижу что-то очень странное, что происходит в приложении 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? Я не могу придумать ничего такого, что могло бы его сломать.

EDIT:

Я провел еще несколько тестов, и это становится все более странным.

Я изменил код, основанный на комментарии Дэвида, чтобы использовать xml..city [0] вместо нового XML (xml..city) для обоих назначений. Это привело к тому, что исключение произошло немного позже (в некотором коде, не показанном выше, где он ссылается на cityXML). Поэтому я попытался войти в отладчик и заметил что-то странное.

cityXML был установлен в null, в то время как stateXML получал правильное значение. Просмотр объекта xml в отладчике показал все правильные данные, поэтому все должно было быть в порядке. В качестве случайного теста я переставил код так, чтобы stateXML загружался первым. После этого stateXML будет нулевым, а 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>

Ответы [ 3 ]

1 голос
/ 02 февраля 2009

Публикация этого ответа как ответа, а не редактирования, поскольку включает некоторые обходные пути.

Я сделал еще несколько тестов. Вот соответствующий код с первого:

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, установленным в нуль. Однако, 2-е присваивание ему дает правильное значение. (Я попытался просто разбить строку cityXML на объявление в одной строке и присвоение в другой, но это не изменило поведение. 2 назначения казались необходимыми).

Другой обходной путь:

LOG.debug("Got response:");
if(xml.length() == 0) { return; }
var cityXML:XML = xml..city[0];
var stateXML:XML = xml..stateProv[0];

Я до сих пор не представляю, почему журнал может привести к тому, что это произойдет, но кажется, что либо добавление трассировки, либо попытка назначения дважды обходит проблему. Я собираюсь продолжить расследование, чтобы выяснить, смогу ли я выяснить основную причину здесь, но, по крайней мере, теперь у меня есть пара обходных путей, которые не включают удаление регистрации.

1 голос
/ 31 января 2009

Это сложный вопрос. Я никогда не использовал классы журналирования, поэтому я не уверен в этой части вопроса, но конвертирую XMLList в XML, как вы делаете:

var cityXML:XML = new XML(xml..city);

работает, только если XMLList содержит один элемент, в противном случае вы получите предупреждение, которое вы цитировали. Вместо этого попробуйте следующую форму:

var cityXML:XML = xml..city[0];

Это работает как для пустых списков, так и для списков со многими элементами. Вы также можете проверить количество детей с помощью xml..city.length() и записать предупреждение, если оно не равно 1. Возможно, это поможет выяснить точную проблему.

Как это достигается добавлением или удалением регистрации звонков, тем не менее, меня больше.

(В некотором родственном замечании я заметил, что объявление и присвоения значения переменной XML в блоке case оператора switch не работает должным образом, т. Е. Назначение просто игнорируется, и переменной не будет присвоено значение. Разрыв строки в двух подсказках. Это также показалось мне ошибкой, поэтому, возможно, не все в порядке с компиляцией связанного с XML кода в AS3.)

0 голосов
/ 02 февраля 2009

Хм. Это выглядит очень похоже на проблему, которую я упомянул. Попробуйте это: переместите объявления переменных 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 */
  }
}

(Опубликовано отдельным ответом, потому что оно сильно отличается от предыдущего.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...