2009-01-30 7 views
4

Je vois quelque chose de très étrange se produire dans une application Flex que je maintiens.La journalisation provoque-t-elle une rupture de l'analyse XML?

Je l'ai parcouru en supprimant tous les appels à trace() et en le remplaçant par des appels dans l'infrastructure de journalisation (en utilisant le contenu mx.logging intégré). Après avoir fait cela, un code d'analyse XML a soudainement cassé, et je ne peux pas pour la vie de moi comprendre pourquoi.

est ici le code:

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 */ 
    } 
} 

Avec le code comme ceci, avec cet appel log.debug() à la place, j'obtiens l'erreur suivante sur la ligne cityXML est définie:

TypeError: Error #1088: The markup in the document following the root element must be well-formed. 

Si je commente l'appel LOG.debug() cela fonctionne très bien.

Je pensais qu'il y avait peut-être un peu de bizarrerie avec la cible de journal personnalisée que j'avais créée, alors j'ai supprimé cela. Actuellement, la seule cible utilisée est la cible de trace intégrée.

Est-ce que quelqu'un sait ce qui se passe? Pourquoi un appel de journalisation rompt l'analyse XML? Je ne peux pas penser à tout ce qu'il pourrait faire pour le briser.

EDIT:

Je l'ai fait d'autres tests, et il est juste obtenir plus étrange.

J'ai changé le code basé sur le commentaire de David pour utiliser xml..city [0] au lieu du nouveau XML (xml..city) pour les deux affectations. Cela a provoqué l'exception un peu plus tard (dans un code non affiché ci-dessus où il fait référence à cityXML). J'ai donc essayé de passer dans le débogueur et j'ai remarqué quelque chose d'étrange. La valeur de cityXML était null, alors que stateXML obtenait la valeur correcte. En regardant l'objet xml dans le débogueur a montré toutes les données correctes, donc cela aurait dû être bien. Comme un test aléatoire, j'ai réarrangé le code de sorte que stateXML a été chargé en premier. Après cela, stateXML est nul, alors que cityXML est correct. Donc, quelle que soit l'affectation qui se produit immédiatement après l'échec du journal, mais quoi qu'il arrive après cela a bien fonctionné.

est ici le (un peu aseptisé) XML qui est en cours d'analyse:

<?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

Pouvez-vous poster le XML que vous essayer de vous connecter? – typeoneerror

Répondre

1

Affichage de ceci comme une réponse au lieu de une modification car elle inclut certaines solutions de contournement.

J'ai fait quelques tests de plus. Voici le code correspondant de la première:

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

Parcourant avec le débogueur, cityXML est affecté à null, alors que stateXML obtient la bonne valeur.

Ensuite, j'ai essayé ceci:

LOG.debug("Got response:"); 
trace("foobar"); 
var cityXML:XML = xml..city[0]; 
var stateXML:XML = xml..stateProv[0]; 

Il a fonctionné! (Pourquoi?!). Les deux cityXML et stateXML ont obtenu les bonnes valeurs. Je ne suis pas satisfait de cela, j'ai essayé un autre test. Je pensais que j'avais juste besoin d'une autre opération entre le journal et la première affectation (aucune idée POURQUOI, mais juste expérimenter ici). J'ai donc essayé ceci:

LOG.debug("Got response:"); 
var someDumbVariable:Number = 42; 
var cityXML:XML = xml..city[0]; 
var stateXML:XML = xml..stateProv[0]; 

Cela n'a pas fonctionné. Donc, encore un test:

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

Cela a fonctionné! Lorsque vous passez par le débogueur, la première affectation se termine par cityXML étant défini sur null. Cependant, la 2ème assignation donne la valeur correcte. (J'ai essayé de diviser simplement la ligne cityXML en une déclaration sur une ligne et l'assignation sur une autre, mais cela n'a pas changé le comportement, 2 affectations semblaient nécessaires).

Une autre solution:

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

Je ne sais toujours pas pourquoi le journal causerait ce genre de choses se produise, mais il semble que ce soit jeter une trace ou d'essayer l'affectation fonctionne deux fois autour de la question. Je vais continuer à enquêter pour voir si je peux comprendre la cause racine ici, mais au moins j'ai maintenant quelques solutions de contournement qui n'impliquent pas de supprimer la journalisation.

+0

Depuis le mien est la seule réponse jusqu'à présent qui a effectivement des solutions de contournement de travail, je vais l'accepter, mais je serais ravi si quelqu'un pouvait trouver une meilleure réponse! – Herms

1

C'est une question difficile. Je ne ai jamais utilisé les classes d'exploitation forestière, donc je ne suis pas sûr de cette partie de la question, mais la conversion d'un XMLList XML comme vous:

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

ne fonctionne que si le XMLList contient un seul élément, sinon vous obtenez le avertissement que vous avez cité. Essayez plutôt le formulaire suivant:

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

Ceci fonctionne aussi bien pour les listes vides que pour les listes comportant de nombreux éléments. Vous pouvez également vérifier le nombre d'enfants avec xml..city.length() et enregistrer un message d'avertissement si ce n'est pas 1. Peut-être cela aidera à comprendre le problème exact.

Comment cela est effectué en ajoutant ou en supprimant des appels de journalisation, mais, me bat.

(Sur une note un peu lié, je remarquai que déclarant et attribuer une valeur à une variable XML dans un bloc case d'une instruction switch ne fonctionne pas comme prévu, à savoir la cession est tout simplement ignorée, et la variable ne sera pas Cela m'a aussi semblé être un bug pour moi, alors peut-être que tout n'est pas correct avec la compilation de code XML dans AS3.)

+0

En regardant le XML analysé, il n'y a qu'un seul nœud "ville". Pareil avec les autres choses qui en sont retirées. Donc, théoriquement, la conversion XML devrait fonctionner correctement. – Herms

+0

Théoriquement, oui. Mais il y a peut-être des bugs avec la gestion XML, comme je l'ai souligné, c'est pourquoi j'ai suggéré d'essayer une notation alternative. Il n'y a pas de mal à essayer. :-) –

+0

Oui, je l'ai essayé. Il a déplacé l'erreur ailleurs dans le code. J'ai mis à jour la question avec des détails. – Herms

0

Hmm. Cela ressemble beaucoup au problème que j'ai mentionné. Essayez ceci: déplacer les déclarations de variables XML à la tête de la fonction:

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 */ 
    } 
} 

(. Posté comme une réponse distincte parce qu'il est tellement différent du précédent)

+0

Non, pas de changement de comportement. Je pense que cela a moins à voir avec la variable et plus avec l'accès au XML. Pour une raison quelconque, la première tentative d'accès ne fonctionne pas correctement. – Herms

Questions connexes