2011-08-24 39 views
6

Tôi có phần sau của tệp xml.Làm thế nào để lấy lại nút cuối cùng bằng cách sử dụng XPath trong C#?

<UN N="@U1"> 
    <DT N="24/06/2011"> 
     <PN N="@P1"> 
      <TM N="02:24:11"> 
       <JB T="GP"> 
        <A>notepad</A> 
        <Z>Notepad</Z> 
        <N>Untitled - Notepad</N> 
        <J>1;0;1;1;0;0</J> 
        <C>0.00500;0.09500;0.03500</C> 
        <S>1;0;1;1</S> 
        <P>0;0</P> 
        <F>0</F> 
       </JB> 
      </TM> 
     </PN> 
    </DT> 

    <DT N="23/06/2011"> 
     <PN N="@P1"> 
      <TM N="02:38:49"> 
       <JB T="PAGP"> 
        <A>notepad</A> 
        <Z>Notepad</Z> 
        <N>Untitled - Notepad</N> 
        <J>1;1;1;1;0;1</J> 
        <C>0.00500;0.09500;0.03500</C> 
        <S>1;1;0;0</S> 
        <P>1;1</P> 
        <F>0</F> 
       </JB> 
      </TM>    
     </PN> 
    </DT> 

    ..... 
    ..... 

</UN> 

Tôi cần có nút cuối cùng PN N = @ P1.

Truy vấn mẫu sẽ được đánh giá cao.

Xin cảm ơn trước.

+0

Bạn đang tìm kiếm tìm thấy một nút '

'hoặc' '? – Richard

Trả lời

5

Chức năng last() XPath có thể được sử dụng để tìm tập cuối của bộ nút. Vì vậy, các <PN> nút cuối cùng với attribyte N có giá trị @P1 sẽ là:

//PN[@N='@P1'][position() = last()] 

Mã NET sẽ phụ thuộc vào XML API bạn đang sử dụng: XmlDocument, XPathDocument hoặc LINQ to XML (XDocument). (Cách tiếp cận với XmlReader sẽ được nạp vào một trong ba và sau đó sử dụng đó.)

Sửa (dựa trên bình luận) Trả lại <F> hậu duệ của người cuối cùng <PN> với thuộc tính như trên, nơi xDoc là một thể hiện của XmlDocument:

var foundNode = xDoc.SelectSingleNode("//PN[@N='@P1'][position() = last()]/TM/JB/F"); 

chỉnh sửa # 2 (dựa trên bình luận khác): trả lại cuối cùng<PN> nơi mỗi <DT> có thể chứa nhiều <DT> các yếu tố trên tất cả các yếu tố <DT>.

Kiểm tra điều này với một số mẫu XML tốt hơn (xem bên dưới), sử dụng XmlElement.SelectNodes và sau đó lặp qua tập nút trả về cho thấy nút phải được tìm thấy, nó không phải là nút đầu tiên và do đó không được trả về bởi SelectSingleNode. Đây là đầu mối: vị từ last() đang được áp dụng trong mỗi kết hợp //PN[@N='@P1']. Một sự thay đổi nhanh chóng ưu tiên là tất cả những gì là cần thiết:

(//PN[@N='@P1'])[last()] 

Để tham khảo trong tương lai, nếu có nhiều yếu tố có thể xảy ra, sau đó hiển thị ít nhất hai trong mẫu, nếu không độc giả sẽ cho rằng trường hợp chỉ số ít . Cũng loại bỏ tất cả các nút (như trẻ em) không cần thiết:

XML mẫu tôi đã sử dụng để thử nghiệm (thêm x thuộc tính để làm cho nó dễ dàng để xác định thành phần được chọn trong khi thử nghiệm):

<UN N='@U1'> 
    <DT N='24/06/2011'> 
    <PN N='@P1' x='#1'/> 
    <PN N='@P1' x='#2'/> 
    <PN N='@P2' x='#3'/> 
    </DT> 

    <DT N='24/06/2011'> 
    <PN N='@P1' x='#4'/> 
    <PN N='@P1' x='#5'/> 
    <PN N='@P2' x='#6'/> 
    </DT> 

    <DT N='24/06/2011'> 
    <PN N='@P3' x='#7'/> 
    <PN N='@P4' x='#8'/> 
    <PN N='@P5' x='#9'/> 
    </DT> 
</UN> 
+0

Cảm ơn, nó hoạt động rất tốt. Điều gì nếu tôi muốn lấy nút cuối cùng của TM/JB/F từ nút trả về. Tôi đang sử dụng lớp XmlDocument. – Syed

+0

Tôi thấy mình.nó sẽ như thế này: '@ "// PN [@N =' @ P1 '] [vị trí() = last()]/TM [position() = last()]/JB/F";' Bất kỳ cảm ơn nào về XPath ban đầu. – Syed

+0

Xin lỗi nhận xét muộn. Nó trả về nút PN cuối cùng của DT, nhưng tôi cần nút cuối cùng bất kể DT trong tệp .xml. Lưu ý: tệp .xml có thể chứa bất kỳ số DT nào và DT bên trong nó chứa nhiều số PN. – Syed

6

Các hoạt động XPath:

"/UN/DT[PN/@N='@p1'][last()]" 

sẽ trở lại cuối cùng DT nút mà [email protected].

Các vấn đề liên quan