2009-12-01 18 views
8

Tôi hiện đang cố gắng xpath saulàm cách nào để có được hàm xpath chuẩn hóa không gian() hoạt động?

//tr[normalize-space(td/text())='User Name'] 

để có được tất cả các tr có chứa một td chứa 'User Name' hoặc 'User Name' hay ' User Name ' nhưng nó không làm việc và tôi không biết những gì là sai với các truy vấn :(
dữ liệu tôi muốn tìm là theo định dạng sau

<tr><td>User Name</td></tr> 
<tr><td>User  Name</td></tr> 
<tr><td> User Name </td></tr> 

Vì vậy, định dạng phù hợp để viết truy vấn xpath này là gì?

Edit: nó dường như không hoạt động nếu các dữ liệu có định dạng sau

<tr><td>x</td><td>User Name</td></tr> 
<tr><td>x</td><td>y</td><td>User  Name</td></tr> 
<tr><td>x</td><td>y</td><td>z</td><td> User Name </td></tr> 

vì vậy bây giờ làm thế nào tôi có thể viết các truy vấn xpath?
lưu ý: "// tr [normalize-space (td/text()) = 'User Name']" wont work
nhưng "// tr/td [normalize-space (text()) = 'Tên người dùng ']" sẽ làm việc (nhưng tôi muốn để có được tr và không phải là yếu tố td)

+0

Vui lòng hiển thị mẫu dữ liệu đầu vào của bạn, bắt đầu bằng ''. –

+0

@Pavel Minaev: Xong :) – Karim

+0

Mọi thứ đều ổn ở cái nhìn đầu tiên. Tôi nghi ngờ vấn đề không phải là với truy vấn, nhưng là với cách bạn sử dụng kết quả. Bạn có thể hiển thị truy vấn trong ngữ cảnh - nếu đó là XSLT, mã XSLT gọi nó và sử dụng kết quả, nếu đó là mã C# trực tiếp, thì mã đó. –

Trả lời

26

Bây giờ bạn đã chỉnh sửa câu hỏi, điều đó có ý nghĩa. Hãy xem xét đầu vào này:

<tr><td>x</td><td>User Name</td></tr> 

và truy vấn không làm việc của bạn:

//tr[normalize-space(td/text()) = 'User Name'] 

Bây giờ, td/text() có nghĩa là "chọn tất cả các nút văn bản con của tất cả các con td nút của nút hiện tại". Trong trường hợp này, điều này sẽ mang lại một tập hợp nút gồm hai nút văn bản, xUser Name.

Bây giờ bạn gọi số normalize-space() trên bộ nút đó. Loại đối số duy nhất của normalize-space()string?. Vì tập hợp nút không phải là chuỗi, chuyển đổi sẽ bắt đầu, theo một đề xuất là section 3.2 của đề xuất XPath 1.0:

Một đối số được chuyển thành chuỗi như thể bằng cách gọi hàm string().

Bây giờ chúng ta hãy nhìn vào definition của string() trong phần 4.2:

Một nút-bộ được chuyển thành một chuỗi bằng cách trả lại chuỗi giá trị của nút trong nút-set đó là lần đầu tiên theo thứ tự tài liệu. Nếu tập hợp nút trống, một chuỗi rỗng sẽ được trả về.

Trong ví dụ của chúng tôi, nút đầu tiên "theo thứ tự tài liệu" là nút văn bản x, vì vậy, nút này sẽ được sử dụng; nút thứ hai bị bỏ qua. Do đó, bạn sẽ gọi số normalize-space('x'). Đương nhiên, điều này sẽ không so sánh bằng 'Tên người dùng'.Để thực hiện việc này, sử dụng:

//tr[td[normalize-space(text()) = 'User Name']] 

Điều này có thể được sao chép lại là "chọn tất cả tr nút có con td nút, đứa trẻ text() nút đầu tiên trong số đó có một giá trị chuỗi bình thường của User Name" - đó là những gì bạn muốn. Hơn nữa, bạn có thể đơn giản hóa này để:

//tr[td[normalize-space() = 'User Name']] 

Từ một không tham số normalize-space() sẽ áp dụng cho nút hiện tại (mà sẽ được td), và xử lý tất cả các nút văn bản bên trong.

1

này hoạt động tốt ở đây:

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.LoadXml(@" 
    <table> 
     <tr><td>User Name</td></tr> 
     <tr><td> User Name </td></tr> 
     <tr><td> User Name </td></tr> 
    </table>"); 

Console.WriteLine(
    xmlDoc.SelectNodes(
     "//tr[td[normalize-space(.) = 'User Name']]").Count); // shows "3" 

bạn có thể vui lòng cập nhật câu hỏi của bạn với một mẫu XML thực tế?

+0

tệp actuall là tệp lớn nên không thể tải lên. nhưng các mẫu giống như một u có nhưng nó không làm việc cho tôi – Karim

+0

bạn không cần phải tải lên toàn bộ tập tin, chỉ mảnh nhỏ, nơi bạn đang gặp vấn đề –

+0

tôi cũng phát hiện ra vấn đề là gì và cập nhật mẫu của tôi – Karim

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