2010-10-04 40 views

Trả lời

98

Kiểm tra các giá trị so với NaN:

<xsl:if test="string(number(myNode)) != 'NaN'"> 
    <!-- myNode is a number --> 
</xsl:if> 

Đây là một phiên bản ngắn hơn (nhờ @Alejandro):

<xsl:if test="number(myNode) = myNode"> 
    <!-- myNode is a number --> 
</xsl:if> 
+10

Bởi vì trong XPath 1.0 'NaN' giá trị của số loại dữ liệu không bằng bất kỳ giá trị số nào và để so sánh nếu ít nhất một đối số là dữ liệu số được nhập thì số kia được truyền thành số, đây là phép thử số ngắn nhất: 'number (MyNode) = MyNode' –

+7

Phiên bản ngắn gọn @Alejandro hoàn toàn không thành công với XPath 2.0 do loại không phù hợp trên th toán tử e = ('Loại mục bắt buộc của toán hạng đầu tiên của '=' là số; giá trị được cung cấp có loại mục xs: string; '), giải pháp của Dimitre hoạt động tốt tuy nhiên. – Lucero

47

Cách ngắn nhất có thể để kiểm tra nếu giá trị chứa trong một biến $v thể được sử dụng làm số là:

number($v) = number($v) 

Bạn chỉ cần thay thế $v ở trên bằng biểu thức có giá trị bạn muốn kiểm tra.

Giải thích:

number($v) = number($v) rõ ràng là đúng, nếu $v là một con số, hoặc một chuỗi đại diện cho một số.

Nó cũng đúng đối với một giá trị boolean, bởi vì một number(true()) là 1 và number(false) là 0.

Bất cứ khi nào $v không thể được sử dụng như một con số, sau đó number($v) là NaN

và NaN không bằng bất kỳ giá trị nào khác, ngay cả với chính nó.

Do đó, biểu thức trên chỉ đúng cho $v có giá trị có thể được sử dụng làm số và sai khác.

+1

+1 giải thích hữu ích. Ai đó có thể bình luận về trường hợp 'số ($ v) = số ($ v)' mang lại kết quả khác với 'số ($ v) = $ v'? – LarsH

+0

@LarsH: Tôi đã nhận xét về những trường hợp này.Bạn có thể chỉ ra một trường hợp không bị phân biệt? –

+0

Tôi có nghĩa là ai đó có thể liệt kê các trường hợp mà 'số ($ v) = số ($ v)' mang lại kết quả khác với 'số ($ v) = $ v'? Không nghi ngờ gì có thể phát sinh từ những gì bạn viết, nhưng tôi không nhìn thấy nơi bạn giải quyết câu hỏi này một cách rõ ràng. Xin lỗi nếu tôi dày đặc. IOW, giải pháp của bạn và giải pháp @ Oded's/@ Alejandro luôn mang lại kết quả tương tự? – LarsH

14

Tôi không cố gắng cung cấp giải pháp thay thế nào khác, mà là "chế độ xem meta" cho vấn đề này.

Câu trả lời đã được Oded và Dimitre Novatchev cung cấp là chính xác nhưng những gì mọi người thực sự có ý nghĩa với cụm từ "giá trị là một số" là, làm cách nào để nói, mở để diễn giải.

Nói cách khác, tất cả đều xuất hiện với câu hỏi nghe kỳ quái này: "bạn muốn thể hiện giá trị số của mình như thế nào?"

chức năng number() số quá trình XPath có

  • có thể đứng đầu hoặc cuối
  • trước dấu nhân vật chỉ trên giá trị âm
  • dot như một phân số thập phân (không bắt buộc đối với số nguyên)
  • tất cả các ký tự khác trong phạm vi [0-9]

Lưu ý rằng điều này không bao gồm biểu cho giá trị số

  • được thể hiện ở dạng lũy ​​thừa (ví dụ 12.3E45)
  • được chứa ký tự dấu hiệu cho các giá trị tích cực
  • có một sự phân biệt giữa tích cực và tiêu cực zero
  • bao gồm giá trị cho vô cực dương hoặc âm

Đây là không chỉ tạo thành tiêu chuẩn. Phần tử có nội dung theo lược đồ giá trị xs:float hợp lệ có thể chứa bất kỳ đặc điểm nào được đề cập ở trên. Tuy nhiên, number() sẽ trả lại giá trị NaN.

Vì vậy, hãy trả lời câu hỏi của bạn "Làm thế nào tôi có thể kiểm tra với XPath nếu giá trị nút là số?" hoặc là "Sử dụng các giải pháp đã đề cập bằng cách sử dụng number()" hoặc "với một biểu thức XPath 1.0 duy nhất, bạn không thể". Hãy suy nghĩ về các định dạng số có thể bạn có thể gặp phải và nếu cần, hãy viết một số loại logic để xác thực/phân tích cú pháp số. Trong quá trình xử lý XSLT, điều này có thể được thực hiện với vài mẫu bổ sung phù hợp, ví dụ.

PS. Nếu bạn chỉ quan tâm về những con số khác không, các bài kiểm tra ngắn nhất là

<xsl:if test="number(myNode)"> 
    <!-- myNode is a non-zero number --> 
</xsl:if> 
+1

+1 Giải thích chi tiết về các vấn đề đằng sau câu hỏi: những gì OP có thể có nghĩa là hoặc sẽ có nghĩa là nếu anh ta biết phải hỏi gì. – LarsH

0

Bạn luôn có thể sử dụng một cái gì đó như thế này:

string(//Sesscode) castable as xs:decimal 

bột nhôm được ghi chép lại bởi W3C here.

9

Người tôi thấy rất hữu ích như sau:

<xsl:choose> 
    <xsl:when test="not(number(myNode))"> 
     <!-- myNode is a not a number or empty(NaN) or zero -->  
    </xsl:when> 
    <xsl:otherwise> 
     <!-- myNode is a number (!= zero) -->   
    </xsl:otherwise> 
</xsl:choose> 
16

Có một nhà điều hành thử nghiệm loại tuyệt vời trong XPath 2.0, bạn có thể sử dụng:

<xsl:if test="$number castable as xs:double"> 
    <!-- implementation --> 
</xsl:if> 
Các vấn đề liên quan