2008-10-28 26 views
5

Son zamanlarda belirli bir XPath ve öznitelik için bir XML dosyasını ayrıştırmak için XPathDocument ve XNavigator kullanıyorum. XPath'in ne olduğunu önceden bildiğimde çok iyi çalışıyor.Bir XML dosyasında XPath varlığı için en iyi yol testi?

Bazen XPath, birkaç olası XPath değerinden biri olacak ve belirli bir XPath olup olmadığını test edebilmek istiyorum. durumda

ben isimlendirme yanlış alıyorum, burada ben bir XPath çağıracağım ne - bu XML blob verilen:

<foo> 
    <bar baz="This is the value of the attribute named baz"> 
</foo> 
Ben "nin bir XPath diyorum neyi arıyor olabilir

// foo/bar "ve sonra değeri almak için" baz "özelliğini okur. Bunu yapmak için kullandıkları kod

Örnek: navigator.SelectSingleNode çağrısı başarısız olursa

XPathDocument document = new XPathDocument(filename); 
XPathNavigator navigator = document.CreateNavigator(); 
XPathNavigator node = navigator.SelectSingleNode("//foo/bar"); 
if(node.HasAttributes) 
{ 
    Console.WriteLine(node.GetAttribute("baz", string.Empty)); 
} 

Şimdi, bu bir NullReferenceException veya XPathException dönecektir. Her ikisini de yakalayabilirim ve verilen bir XPath'in bir istisna getirip getirmediğini görmek için yukarıdaki testi tekrar test edebilirim, ama daha iyi bir yol olup olmadığını mı merak ediyordum?

Intellisense'de bariz bir şey görmedim. XPathNavigator vardır .HasAttributes ve .HasChildren ama bir seferde bir düğümün yolu boyunca yinelemenin kısa, kullanmak için daha güzel bir şey görmüyorum. Geçerli XPath verdik ama bir şey uymuyorsa

+0

Bunun LINQ ile ilgisi nedir? XPathNavigator ve XPathDocument, LINQ to XML'in bir parçası değildir. –

cevap

10

, SelectSingleNode değil atmak bir NullReferenceException olacak - bu sadece boş dönecektir.

SelectSingleNode bazı sözdizimsel olarak geçersiz XPath iletirseniz, XPathException atar.

Normal olarak, yalnızca döndürülen değerin sıfır olup olmadığını sınamanız gerekir.

+0

Aradığım şey bu, teşekkürler. –

0

Bellekten, hatalar içerebilir.

XDocument doc = XDocument.Load("foo.xml"); 

var att = from a in doc.Descendants("bar") 
      select a.Attribute("baz") 

foreach (var item in att) { 
    if (item != null) { ... } 
} 
+0

Soru başlığı Linq'den bahsettiğinden, bunu nasıl yapacağım. –

+0

Kullanın.FirstOrDefault sadece tek –

0

node == null sonra node.HasAttributes bir NullReferenceException atacağım. Bu durum, //foo/bar XML belgesindeki herhangi bir öğeyle eşleşmediğinde ortaya çıkar.

0
var node = XDocument.Load(filename) 
        .Descendants("bar") 
        .SingleOrDefault(e=>e.Attribute("baz") != null); 

if (node != null) Console.WriteLine(node.Attribute("baz").Value); 
1
var baz = navigator.SelectSingleNode("//foo/bar/@baz"); 
if (baz != null) Console.WriteLine(baz); 
0

Herhalde benim XPath'de daha çok belli olur.

 var doc = XDocument.Load(fileName); 

     var results = from r in doc.XPathSelectElements("/foo/bar[count(@baz) > 0]") 
         select r.Attribute("baz"); 

     foreach (String s in results) 
      Console.WriteLine(s); 
1

Ben navigator.SelectSingleNode (...) yürüterek bir XMLNode nesnesi oluşturmak için iyi olmadığını düşünüyorum. Bunun yerine) navigator.Evaluate (kullanmak zorunda

:

if (Convert.ToBoolean(navigator.Evaluate(@"boolean(//foo/bar)"))) {...} 
+0

I (bir dize olarak XPath ifadesi, derlenmemiş ile) 500.000 tekrarlamalar her biri için, SelectSingleNode kıyasla bu yöntemin bir hız karşılaştırma yaptı istiyorsanız sorguyu. SelectSingleNode yöntemi, boole yönteminden% 16-18 daha hızlıydı. Testi birkaç kez tekrarladım ve sonuçlar tutarlı. –

İlgili konular