2011-08-12 33 views
13

Nếu tôi có XML bên dưới, cách chỉ định một xpath để trả về chuỗi dựa trên điều kiện. Ví dụ tại đây if //b[@id=23] then "Profit" else "Loss"Trả lại giá trị chuỗi dựa trên điều kiện XPATH

<a> 
    <b id="23"/> 
    <c></c> 
    <d></d> 
    <e> 
    <f id="23"> 
     <i>123</i> 
     <j>234</j> 
    <f> 
    <f id="24"> 
     <i>345</i> 
     <j>456</j> 
    <f> 
    <f id="25"> 
     <i>678</i> 
     <j>567</j> 
    <f> 
    </e> 
</a> 
+0

Câu hỏi hay, +1. Xem câu trả lời của tôi cho một biểu thức một lớp XPath 1.0 thuần túy. :) –

+0

Cũng được giải thích rộng rãi và giải pháp XPath 2.0 rõ ràng. –

Trả lời

19

I. XPath giải pháp 2.0 (khuyến cáo nếu bạn có quyền truy cập vào một công cụ XPath 2.0)

(: XPath 2.0 has if ... then ... else ... :) 

    if(//b[@id=23]) 
    then 'Profit' 
    else 'Loss' 

II. XPath giải pháp 1.0:

Sử dụng:

concat(substring('Profit', 1 div boolean(//b[@id=23])), 
     substring('Loss', 1 div not(//b[@id=23])) 
    ) 

xác nhận sử dụng XSLT 1.0:

chuyển đổi này:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:value-of select= 
    "concat(substring('Profit', 1 div boolean(//b[@id=23])), 
      substring('Loss', 1 div not(//b[@id=23])) 
     )"/> 
</xsl:template> 
</xsl:stylesheet> 

khi áp dụng trên tài liệu XML cung cấp (điều chỉnh để làm cho nó được hình thành tốt):

<a> 
    <b id="23"/> 
    <c></c> 
    <d></d> 
    <e> 
     <f id="23"> 
      <i>123</i> 
      <j>234</j> 
     </f> 
     <f id="24"> 
      <i>345</i> 
      <j>456</j> 
     </f> 
     <f id="25"> 
      <i>678</i> 
      <j>567</j> 
     </f> 
    </e> 
</a> 

tạo ra truy nã, chính xác kết quả:

Profit 

Khi chúng ta thay thế trong văn bản XML:

<b id="23"/> 

với:

<b id="24"/> 

lại kết quả chính xác được sản xuất:

Loss 

Giải thích:

Chúng tôi sử dụng thực tế là:

substring($someString, $N) 

là chuỗi rỗng cho tất cả $N > string-length($someString).

Ngoài ra, số Infinity là số duy nhất lớn hơn độ dài chuỗi của bất kỳ chuỗi.

Cuối cùng:

number(true())1 theo định nghĩa,

number(false())0 theo định nghĩa.

Do đó:

1 div $someCondition

1 chính xác khi $someConditiontrue()

và là Infinity chính xác khi nào $someConditionfalse()

Như vậy nó sau từ này rằng nếu chúng ta muốn sản xuất $stringX khi $Condtrue() và để sản xuất $stringY khi $Condfalse(), một cách để thể hiện điều này bằng cách:

concat(substring($stringX, 1 div $cond), 
     substring($stringY, 1 div not($cond)), 
    ) 

Trong biểu thức trên chính xác một trong hai đối số của concat() chức năng không bị để trống.

+1

+1 Dimitre bạn luôn cung cấp các giải thích nổi bật, đặc biệt là các câu hỏi liên quan đến XPath. Tôi nói từ kinh nghiệm :) – Dan

+0

@Bracketworks, bạn được chào đón. –

+2

1 giải pháp rất mát mẻ –

0

Bạn không thể; bạn phải sử dụng XQuery cho việc này. xem ví dụ XQuery Conditional Expressions

Hoặc, nếu chuỗi kết quả chỉ được sử dụng trong Java, bạn chỉ có thể xử lý các giá trị được trả về bởi XPath trong mã Java của bạn:

XPathFactory factory = XPathFactory.newInstance(); 
XPath xpath = factory.newXPath(); 
XPathExpression expr = xpath.compile("//b[@id=23]"); 
boolean result = expr.evaluate(doc, XPathConstants.BOOLEAN); 

if (result) return "Profit"; 
else return "Loss"; 
+0

Tôi đang sử dụng JAXP để xử lý xml. Làm thế nào để sử dụng xquery này trong này? –

+0

Nếu bạn đang sử dụng JAXP, thì tại sao không chỉ kiểm tra giá trị chuỗi đã truy xuất ở phía Java? –

+0

Vấn đề của tôi dựa trên giá trị thuộc tính nút, tôi phải quyết định chuỗi kết quả. Khi tôi cố gắng lấy chuỗi không có gì xuất hiện vì nút này chỉ có một thuộc tính . Nếu tôi cho conditon như // b [@ id = 23] thì nó trả về giá trị boolen. –

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