2010-08-06 11 views
18

Document कक्षा के लिए जावाडोक getElementById के तहत निम्न नोट है।जावा एक्सएमएल डोम: आईडी विशेष विशेषताएं कैसे हैं?

नोट: नाम "आईडी" या "आईडी" के साथ गुण प्रकार आईडी जब तक ऐसा परिभाषित

तो नहीं कर रहे हैं, मैं डोम में एक XHTML दस्तावेज़ (Xerces 2.9.1 का प्रयोग करके) पढ़ा ।

इस दस्तावेज़ में एक सादा पुराना <p id='fribble'> है।

मैं getElementById("fribble") पर कॉल करता हूं, और यह शून्य हो जाता है।

मैं "// * [id = 'fribble'] प्राप्त करने के लिए XPath का उपयोग करता हूं, और सब ठीक है।

तो सवाल यह है कि DocumentBuilder वास्तव में आईडी विशेषताओं को 'इतना परिभाषित' के रूप में चिह्नित करने का कारण क्या है?

उत्तर

16

getElementById() काम करने के लिए कॉल करने के लिए, Document को अपने नोड्स के प्रकारों को जानना है, और लक्ष्य नोड इसे खोजने के लिए XML आईडी प्रकार का होना चाहिए। यह संबंधित तत्वों के माध्यम से इसके तत्वों के प्रकारों के बारे में जानता है। यदि स्कीमा सेट नहीं है, या XML ID प्रकार के id विशेषता को घोषित नहीं करता है, तो getElementById() इसे कभी नहीं मिलेगा।

मेरा अनुमान है कि आपका दस्तावेज़ p तत्व की id विशेषता नहीं है XML आईडी प्रकार (है ना?) है। आप getChildNodes() और अन्य डोम-ट्रैवर्सल फ़ंक्शंस का उपयोग करके डोम में नोड पर नेविगेट कर सकते हैं, और सुनिश्चित करने के लिए आईडी विशेषता पर Attr.isId() पर कॉल करने का प्रयास करें।

getElementById जावाडोक से

:

डोम कार्यान्वयन होने की उम्मीद है विशेषता को Attr.isId का उपयोग यह निर्धारित करता है, तो एक विशेषता के प्रकार आईडी है।

नोट: "आईडी" या "आईडी" नाम के साथ गुण टाइप आईडी नहीं हैं जब तक परिभाषित नहीं किया जाता है।

आप एक DocumentBuilder उपयोग कर रहे हैं एक डोम में अपने XML पार्स करने के लिए, newDocumentBuilder(), कॉल करने से पहले DocumentBuilderFactory पर setSchema(schema) कॉल करने के लिए सुनिश्चित करना है कि बिल्डर आप कारखाने से प्राप्त तत्व प्रकार के बारे में पता है सुनिश्चित हो ।

4

आईडी विशेषता एक विशेषता नहीं है जिसका नाम "आईडी" है, यह एक विशेषता है जिसे डीटीडी या स्कीमा द्वारा आईडी विशेषता घोषित किया जाता है। उदाहरण के लिए, एचटीएमएल 4 DTD यह वर्णन करता है:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
3

इसी xpath एक्सप्रेशन वास्तव में id('fribble'), जो getElementById के रूप में एक ही परिणाम लौट जाना होगा। इसके लिए काम करने के लिए, आपके दस्तावेज़ से जुड़े डीटी या स्कीमा को विशेषता आईडी के रूप में विशेषता घोषित करना है।

यदि आप पूछे गए एक्सएमएल के नियंत्रण में हैं तो आप xml:id पर http://www.w3.org/TR/xml-id/ के अनुसार विशेषता का नाम बदलने का भी प्रयास कर सकते हैं।

47

ये गुण उनके प्रकार के कारण विशेष हैं और उनके नाम के कारण नहीं हैं।

एक्सएमएल

हालांकि यह मान के साथ name="value" के रूप में विशेषताओं के बारे में सोच रहा है एक सरल स्ट्रिंग जा रहा है, कि पूरी कहानी नहीं है आसान है में

आईडी - वहाँ भी एक विशेषता प्रकार के साथ जुड़े है जिम्मेदार बताते हैं।

एक्सएमएल स्कीमा में शामिल होने पर यह सराहना करना आसान है, क्योंकि एक्सएमएल स्कीमा एक्सएमएल तत्वों और एक्सएमएल विशेषताओं दोनों के लिए डेटाटाइप का समर्थन करता है। एक्सएमएल विशेषताओं को एक साधारण प्रकार के रूप में परिभाषित किया जाता है (उदा। एक्सएस: स्ट्रिंग, एक्सएस: पूर्णांक, एक्सएस: डेटटाइम, एक्सएस: anyURI)। यहां पर विचार किए जा रहे गुणों को xs:ID अंतर्निहित डाटाटाइप (section 3.3.8 of the XML Schema Part 2: Datatypes देखें) के साथ परिभाषित किया गया है।

<xs:element name="foo"> 
    <xs:complexType> 
    ... 
    <xs:attribute name="bar" type="xs:ID"/> 
    ... 
    </xs:complexType> 
</xs:element> 

हालांकि DTD XML स्कीमा में अमीर डेटाटाइप्स का समर्थन नहीं करते हैं, यह विशेषता प्रकार (जो section 3.3.1 of XML 1.0 में परिभाषित किया गया है) के एक सीमित सेट का समर्थन करता है। यहां चर्चा की जा रही विशेषताओं को विशेषता प्रकारID के साथ परिभाषित किया गया है।

<!ATTLIST foo bar ID #IMPLIED> 

या तो ऊपर XML स्कीमा या DTD के साथ, निम्नलिखित तत्व "xyz" के ID मान द्वारा की पहचान की जाएगी।

<foo bar="xyz"/> 

XML स्कीमा या DTD जानने के बिना, वहाँ कोई रास्ता नहीं एक आईडी है और क्या क्या यह बताने के लिए किया जाता है नहीं: "आईडी" के नाम के साथ

  • गुण आवश्यक रूप से की जरूरत नहीं है आईडी के विशेषता प्रकार; और
  • उन नामों के साथ विशेषताएँ जो "आईडी" नहीं हैं, उनमें विशेषता प्रकार आईडी का हो सकता है!

इस स्थिति में सुधार के लिए, xml:id बाद में आविष्कार किया गया था (देखें xml:id W3C Recommendation)। यह एक विशेषता है जिसमें हमेशा एक ही उपसर्ग और नाम होता है, और इसका उद्देश्य विशेषता प्रकार आईडी के साथ एक विशेषता के रूप में माना जाना है। हालांकि, यह करता है कि इस्तेमाल किए जाने वाले पार्सर पर निर्भर करेगा xml:id या नहीं। चूंकि xml:id परिभाषित होने से पहले कई पार्सर्स को प्रारंभ में लिखा गया था, इसलिए यह समर्थित नहीं हो सकता है। जावा

जावा में, getElementById() में

आईडी की प्रकार आईडी गुण की तलाश में, नाम "आईडी" के साथ विशेषताओं के लिए नहीं द्वारा तत्वों पाता है।

उपरोक्त उदाहरण में, getElementById("xyz") कि foo तत्व वापस आ जाएगी, भले ही उस पर विशेषता का नाम "आईडी" नहीं है (डोम संभालने जानता bar एक विशेषता प्रकार आईडी छोटा है)।

तो डोम को कैसे पता चलता है कि विशेषता प्रकार एक विशेषता है? वहाँ तीन तरीके हैं:

  1. पार्सर के लिए एक XML स्कीमा प्रदान करें (example)
  2. पार्सर
  3. स्पष्ट रूप से डोम कि यह आईडी की एक विशेषता प्रकार के रूप में व्यवहार किया जाता है करने के लिए इंगित करने के लिए एक DTD प्रदान करें।

तीसरा विकल्प org.w3c.dom.Element class पर setIdAttribute() या setIdAttributeNS() या setIdAttributeNode() तरीकों का उपयोग कर किया जाता है।

Document doc; 
Element fooElem; 

doc = ...; // load XML document instance 
fooElem = ...; // locate the element node "foo" in doc 

fooElem.setIdAttribute("bar", true); // without this, 'found' would be null 

Element found = doc.getElementById("xyz"); 

यह प्रत्येक तत्व नोड के लिए किया जाना चाहिए जिसमें इन प्रकार के गुणों में से एक है। विशेषता प्रकार आईडी के किसी दिए गए नाम (उदा। "आईडी") के साथ विशेषताओं की सभी घटनाओं को बनाने के लिए कोई आसान अंतर्निहित विधि नहीं है।

यह तीसरा दृष्टिकोण केवल उन स्थितियों में उपयोगी है जहां getElementById() को कॉल करने वाला कोड डीओएम बनाने से अलग है। यदि यह वही कोड था, तो इसे पहले से ही आईडी विशेषता सेट करने के लिए तत्व मिला है, इसलिए getElementById() पर कॉल करने की आवश्यकता नहीं है।

साथ ही, ध्यान रखें कि वे विधियां मूल डोम विनिर्देशन में नहीं थीं। getElementById को DOM level 2 में पेश किया गया था। क्योंकि यह केवल विशेषता नाम मिलान किया गया था

XPath

XPath मूल प्रश्न में में

आईडी एक परिणाम दे दी है।

विशेषता प्रकार आईडी मूल्यों पर से मेल करने के लिए, XPath id समारोह में इस्तेमाल किया जा करने की जरूरत है (यह Node Set Functions from XPath 1.0 में से एक है):

id("xyz") 

कि इस्तेमाल किया गया था, तो XPath दिया होता getElementById() (यानी कोई मिलान नहीं मिला) के समान परिणाम।

एक्सएमएल में

आईडी जारी रखा आईडी

दो महत्वपूर्ण विशेषताएं प्रकाश डाला जाना चाहिए।

सबसे पहले, की सभी विशेषताओं के गुणधर्म मान प्रकार आईडी पूरे XML दस्तावेज़ को अद्वितीय होना चाहिए। निम्नलिखित उदाहरण में, यदि personId और companyId दोनों में विशेषता प्रकार आईडी है, तो आईडी24601 के companyId के साथ एक और कंपनी जोड़ने की त्रुटि होगी, क्योंकि यह मौजूदा आईडी मान का डुप्लिकेट होगा। भले ही विशेषता नाम अलग हैं, यह विशेषता प्रकार महत्वपूर्ण है।

<test1> 
<person personId="id24600">...</person> 
<person personId="id24601">...</person> 
<company companyId="id12345">...</company> 
<company companyId="id12346">...</company> 
</test1> 

दूसरे, गुण तत्वों बजाय पूरे XML दस्तावेज़ पर परिभाषित कर रहे हैं। इसलिए विभिन्न तत्वों पर एक ही विशेषता नाम के साथ गुण अलग-अलग विशेषता प्रकार गुण हो सकते हैं। निम्न उदाहरण XML दस्तावेज़ में, यदि केवल alpha/@bar आईडी एक विशेषता प्रकार है (और कोई अन्य विशेषता थी), getElementById("xyz") एक तत्व वापस आ जाएगी, लेकिन getElementById("abc") नहीं होगा (के बाद से beta/@barविशेषता प्रकार आईडी नहीं है)। साथ ही, यह gamma/@bar के लिए alpha/@bar के समान मान रखने के लिए विशेषता नहीं है, यह मान XML दस्तावेज़ में आईडी की विशिष्टता में नहीं माना जाता है क्योंकि यह विशेषता प्रकार आईडी नहीं है।

<test2> 
    <alpha bar="xyz"/> 
    <beta bar="abc"/> 
    <gamma bar="xyz"/> 
</test2> 
+0

+1 अच्छा जवाब! मैंने आज कुछ नया सीखा। –

+0

दुर्भाग्यवश, स्कीमा उदाहरण का लिंक अब तक मर चुका है। – ferkulat

1

निम्नलिखित आप आईडी से एक तत्व प्राप्त करने के लिए अनुमति देगा:

public static Element getElementById(Element rootElement, String id) 
{ 
    try 
    { 
     String path = String.format("//*[@id = '%1$s' or @Id = '%1$s' or @ID = '%1$s' or @iD = '%1$s' ]", id); 
     XPath xPath = XPathFactory.newInstance().newXPath(); 
     NodeList nodes = (NodeList)xPath.evaluate(path, rootElement, XPathConstants.NODESET); 

     return (Element) nodes.item(0); 
    } 
    catch (Exception e) 
    { 
     return null; 
    } 
} 
संबंधित मुद्दे