2010-07-22 6 views
1

J'ai une structure XML comme suit:Way Lisible Pour la première Retour XPath Résultat

<Root> 
    <Base> 
     <Greeting>Base Hello!</Greeting> 
     <SpecialMessage>Base Special Message</SpecialMessage> 

     <Products> 
      <Product id="001"> 
       <Greeting>Base 001 Hello!</Greeting> 
      </Product> 
     </Products> 
    </Base> 

    <Buy> 
     <Greeting>Buy Hello!</Greeting> 
     <SpecialMessage>Buy Special Message</SpecialMessage> 
     <Products> 
      <Product id="001"> 
       <Greeting>Buy 001 Hello!</Greeting> 
      </Product> 
     </Products> 
    </Buy> 

    <Rent> 
     <Greeting>Rent Hello</Greeting> 
    </Rent> 
</Root> 

La base, Acheter et louer des nœuds existera toujours, mais les nœuds dans les peuvent ou non. Lors de l'exécution, je vais déterminer si cela est un scénario Acheter ou louer. Je peux aussi avoir ou non un identifiant de produit. Par exemple, si c'est un scénario d'achat et que l'identifiant du produit est "001", je recevrai le message "Acheter Bonjour 001". Toutefois, si la section de produit dans la section Acheter devait manquer pour une raison quelconque, je vais y retourner « Base 001 Bonjour ».

Un deuxième exemple serait si je voulais obtenir le SpecialMessage pour un scénario de location. Puisque aucun nœud SpecialMessage est dans la section Location, je vais y retourner « Base message spécial »

je établir une liste de XPath comme celui-ci, en utilisant Greeting comme un exemple dans un scénario Acheter pour le produit 001):

  1. /Root/Acheter/Produits/produit [id = 001]/Greeting
  2. /Root/base/Produits/produit [id = 001]/Greeting
  3. /Root/Achat/Greeting
  4. /Root/Base/accueil

En ce moment, je commence en haut de la liste, exécutez la XPath, renvoie le résultat si elle a trouvé, autre sage à la prochaine XPath et ainsi de suite:

string result; 
result = RunXPath(xpaths["Level1"], document); 
if (!String.IsNullOrEmpty(result)) 
    return result; 

result = RunXPath(xpaths["Level2"], document); 
if (!String.IsNullOrEmpty(result)) 
    return result; 

result = RunXPath(xpaths["Level3"], document); 
if (!String.IsNullOrEmpty(result)) 
    return result; 

result = RunXPath(xpaths["Level4"], document); 
if (!String.IsNullOrEmpty(result)) 
    return result; 

return String.Empty; 

Alors que cela fonctionne, il semble maladroit et un peu difficile à lire. Y a-t-il de meilleures approches en termes de lisibilité?

+0

Pourquoi faites-vous pas que dans une boucle? RunXPath (xpaths ["Level" + i.ToString()], document); –

Répondre

0

Une option consiste à créer une collection de chemins, et itérer dessus:

string[] paths = {"Level1", "Level2", "Level3", "Level4"}; 
foreach(string path in paths) 
{ 
    result = RunXPath(xpaths[path], document); 
    if (!String.IsNullOrEmpty(result)) 
     return result; 
} 
return ""; 

En général, si vous vous trouvez à écrire du code répété, vous devriez envisager d'utiliser une boucle ou une méthode (ou les deux!) .
Aussi, essayez de ne pas utiliser la même variable pour des choses différentes. Optez pour des noms significatifs - il aidera la lisibilité, et aider à détecter les erreurs. C'est moins offensant dans votre sénarion, mais assez important. Considérez:

result = RunXPath(xpaths["/document/my:things/rooms[0]/floor"], document); 
Print(result); 
result = RunXPath(xpaths["/document/my:things/roomate/phone/mobile"], document); 
Print(result); 

J'ai eu récemment au code de débogage exactement comme ça, et à remaniée avec:

string floor = RunXPath(xpaths["/document/my:things/rooms[0]/floor"], document); 
Print(floor); 
string friendMobilePhone = RunXPath(xpaths["/document/my:things/roomate/phone/mobile"], document); 
Print(friendMobilePhone);