2010-08-16 12 views
6

साथ जैसे मैं XML दस्तावेज़ों है:xpath 'या' संघ की तरह बर्ताव कर ('|') xmllib2

<rootelement> 
<myelement>test1</myelement> 
<myelement>test2</myelement> 
<myelement type='specific'>test3</myelement> 
</rootelement> 

मैं विशिष्ट myelement पुनः प्राप्त करना चाहते हैं, और अगर यह तो उपस्थित नहीं है, पहला वाला। तो मैं लिखना:

/rootelement/myelement[@type='specific' or position()=1] 

'या' अभिव्यक्ति है कि के बारे में XPath spec कहता है:

सही संकार्य का मूल्यांकन नहीं है, तो बाईं संकार्य सच

समस्या का मूल्यांकन यह है कि libxml2-2.6.26 दोनों अभिव्यक्तियों का संघ लागू करता है, "2 नोड सेट" लौटाता है (उदाहरण के लिए xmllint --shell का उपयोग करना)।

क्या यह libxml2 है या क्या मैं कुछ गलत कर रहा हूं?

+0

अच्छा प्रश्न (+1):

यहाँ एक XPath एक लाइनर का चयन वास्तव में क्या आप चाहते हैं। एक एकल XPath अभिव्यक्ति के लिए मेरा उत्तर देखें जो वास्तव में आपके इच्छित नोड का चयन करता है। :) –

उत्तर

10

संक्षिप्त उत्तर: आपका चयनकर्ता जो व्यक्त करता है उसे व्यक्त नहीं करता है।


or ऑपरेटर एक संघ है।

आपके द्वारा उद्धृत स्पेस का हिस्सा ("सही ऑपरेंड का मूल्यांकन नहीं किया जाता है ...") मानक boolean logic short circuiting का हिस्सा है।

यहाँ क्यों आप अपने उदाहरण इनपुट के लिए एक 2-नोड सेट प्राप्त होते हैं: XPath हर myelementrootelement का एक बच्चा है कि को देखता है, और चाहे या नहीं यह चयनकर्ता से मेल खाता निर्धारित करने के लिए इस तरह के प्रत्येक नोड के लिए [@type='specific' or position()=1] हिस्सा लागू होता है।

  1. <myelement>test1</myelement>@type='specific' का मिलान नहीं करती है, लेकिन यह मैच position()=1 करता है, तो यह पूरी चयनकर्ता से मेल खाता।
  2. <myelement>test2</myelement>@type='specific' से मेल नहीं खाता है, और यह position()=1 से मेल नहीं खाता है, इसलिए यह पूरे चयनकर्ता से मेल नहीं खाता है।
  3. <myelement type='specific'>test3</myelement> मैचों @type='specific' (इसलिए XPath को अपनी स्थिति का परीक्षण करने की आवश्यकता नहीं है - यह शॉर्ट सर्किटिंग हिस्सा है) इसलिए यह पूरे चयनकर्ता से मेल खाता है।

पहला और अंतिम <myelement> एस पूरे चयनकर्ता से मेल खाता है, इसलिए यह 2-नोड सेट देता है।

तत्वों का चयन करने का सबसे आसान तरीका यह है कि आप इसे दो चरणों में करना चाहते हैं।यहाँ स्यूडोकोड है (मैं क्या संदर्भ आप वास्तव में XPath का उपयोग कर रहे पता नहीं है, और मुझे लगता है कि लेखन XPath-वाक्य रचना चयनकर्ताओं से परिचित नहीं हूँ):

  1. करें elements से मेल खाने वाले /rootelement/myelement[@type='specific']
  2. तो elements खाली है, elements से मेल खाने वाले /rootelement/myelement[position()=1]
+0

आपको खाएगा: बहुत अच्छी व्याख्या के लिए +1! –

7

@Matt गेंद बहुत अच्छी तरह से आपकी समस्या का कारण बताया गया है का चयन करें।

/*/myelement[@type='specific'] | /*[not(myelement[@type='specific'])]/myelement[1] 
+0

डिमिट्रे, आपकी अभिव्यक्ति में एक गायब समापन ') लगता है। आपकी अभिव्यक्ति बिल्कुल वही नोड का चयन करती है, अर्थात् test1 और test3, जो मेरा इरादा नहीं है। बीटीडब्ल्यू, मैंने भी कोशिश की (/ rootelement/myelement [@ type = 'विशिष्ट' या स्थिति() = 1]) [1], जो मुझे test1 देता है ... बेहतर नहीं। – foudfou

+0

@foudfou: इसे ध्यान में रखने के लिए धन्यवाद। मैंने इसे अभी तय किया है, इसलिए एक बार और कोशिश करें। :) –

संबंधित मुद्दे