अवलोकन
एक्सएमएल दस्तावेज़ श्रेणीबद्ध दस्तावेज हैं, जहां एक ही तत्व के नाम और नामस्थान कई स्थानों पर हो सकते हैं, अलग-अलग अर्थ होते हैं, और असीम गहराई (पुनरावर्ती) में होते हैं। सामान्य के रूप में, बड़ी समस्याओं का समाधान, उन्हें छोटी समस्याओं में विभाजित करना है। XML पार्सिंग के संदर्भ में, इसका मतलब है कि XML के विशिष्ट तरीकों में XML के विशिष्ट भागों को पार्स करना। उदाहरण के लिए, तर्क का एक टुकड़ा एक पते को पार्स करेगा:
<Address>
<Street>Odins vei</Street>
<Building>4</Building>
<Door>b</Door>
</Address>
यानी आपके पास एक तरीका होगा
AddressType parseAddress(...);
या
void parseAddress(...);
अपने तर्क में कहीं, एक्सएमएल इनपुट तर्कों को लेने और एक वस्तु वापस करने (बी के परिणाम को बाद में एक क्षेत्र से प्राप्त किया जा सकता है)।
SAX
SAX 'XML' आयोजनों को आगे बढ़ाता है , जिससे यह निर्धारित होता है कि आपके कार्यक्रम / डेटा में XML इवेंट कहाँ हैं।
// method in stock SAX handler
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
// .. your logic here for start element
}
'बिल्डिंग' स्टार्ट तत्व के मामले में, आपको यह निर्धारित करना होगा कि आप वास्तव में एक एड्रेस पार्स कर रहे हैं और फिर एक्सएमएल ईवेंट को उस विधि पर रूट करें, जिसका काम एड्रेस की व्याख्या करना है।
StAX
StAX 'XML घटनाओं को खींचता है , जिससे यह निर्धारित होता है कि XML कार्यक्रम प्राप्त करने के लिए आपके प्रोग्राम / डेटा में कहाँ निर्धारित किया गया है।
int event = reader.next();
if(event == XMLStreamConstants.START_ELEMENT) {
}
बेशक, आप हमेशा उस विधि में एक 'बिल्डिंग' इवेंट प्राप्त करना चाहेंगे जिसका काम एड्रेस की व्याख्या करना है।
चर्चा
SAX और StAX के बीच का अंतर धक्का और खींच है। दोनों मामलों में, पार्स राज्य को किसी भी तरह से संभाला जाना चाहिए।
यह B को SAX के लिए विशिष्ट विधि के रूप में अनुवाद करता है, और StAX के लिए विधि A। इसके अलावा, SAX को B अलग-अलग XML इवेंट्स देने चाहिए, जबकि Stax एक मल्टीपल इवेंट्स (XMLStreamReader इंस्टेंस पास करके) दे सकता है।
इस प्रकार बी पहले पार्सिंग की पिछली स्थिति की जांच करते हैं और फिर प्रत्येक व्यक्तिगत एक्सएमएल घटना को संभालते हैं और फिर राज्य (एक क्षेत्र में) को स्टोर करते हैं। विधि A केवल XMLStreamReader को एक बार में संतुष्ट होने तक कई बार XML घटनाओं को संभाल सकती है।
निष्कर्ष
StAX आपको XML संरचना के अनुसार अपने पार्सिंग (डेटा-बाइंडिंग) कोड की संरचना करने देता है ; इसलिए SAX के संबंध में, 'स्टेट' का अर्थ StAX के लिए प्रोग्राम फ्लो से है, जबकि SAX में, आपको हमेशा किसी न किसी प्रकार के स्टेट वेरिएबल + रूट को उस स्थिति के अनुसार संरक्षित करने की आवश्यकता होती है, अधिकांश इवेंट कॉल के लिए।
मैं सभी लेकिन सरलतम दस्तावेजों के लिए StAX की सलाह देता हूं। बाद में SAX को एक अनुकूलन के रूप में स्थानांतरित करें (लेकिन आप तब तक बाइनरी जाना चाहेंगे)।
Stax का उपयोग करते समय इस पैटर्न का पालन करें:
public MyDataBindingObject parse(..) {
XMLStreamReader reader = ....;
do {
int event = reader.next();
if(event == XMLStreamConstants.START_ELEMENT) {
break;
}
} while(reader.hasNext());
MyDataBindingObject object = new MyDataBindingObject();
int level = 1;
do {
int event = reader.next();
if(event == XMLStreamConstants.START_ELEMENT) {
level++;
if(reader.getLocalName().equals("Whatever1")) {
WhateverObject child = parseSubTreeForWhatever(reader);
level --;
object.setWhatever(child);
}
if(level == 2) {
parseSubTreeForWhateverAtRelativeLevel2(reader);
level --;
object.setWhatever(child);
}
} else if(event == XMLStreamConstants.END_ELEMENT) {
level--;
}
} while(level > 0);
return object;
}
तो एक ही दृष्टिकोण के बारे में सबमिथोड उपयोग करता है, यानी गिनती स्तर:
private MySubTreeObject parseSubTree(XMLStreamReader reader) throws XMLStreamException {
MySubTreeObject object = new MySubTreeObject();
int level = 1;
do {
int event = reader.next();
if(event == XMLStreamConstants.START_ELEMENT) {
level++;
if(reader.getLocalName().equals("Whatever2")) {
MyWhateverObject child = parseMySubelementTree(reader);
level --;
object.setWhatever(child);
}
if(level == 2) {
MyWhateverObject child = parseMySubelementTree(reader);
level --;
object.setWhatever(child);
}
} else if(event == XMLStreamConstants.END_ELEMENT) {
level--;
}
} while(level > 0);
return object;
}
और फिर अंततः आप एक स्तर तक पहुंच जाते हैं जिसमें आप आधार प्रकार पढ़ेंगे।
private MySetterGetterObject parseSubTree(XMLStreamReader reader) throws XMLStreamException {
MySetterGetterObject myObject = new MySetterGetterObject();
int level = 1;
do {
int event = reader.next();
if(event == XMLStreamConstants.START_ELEMENT) {
level++;
if(reader.getLocalName().equals("FirstName")) {
String text = reader.getElementText()
if(text.length() > 0) {
myObject.setName(text)
}
level--;
} else if(reader.getLocalName().equals("LastName")) {
}
} else if(event == XMLStreamConstants.END_ELEMENT) {
level--;
}
} while(level > 0);
return myObject;
}
यह काफी सीधा है और गलतफहमी के लिए कोई जगह नहीं है। बस सही ढंग से वृद्धि स्तर को याद रखें:
ए के बाद आप पात्रों की उम्मीद करते हैं, लेकिन कुछ टैग में एक END_ELEMENT मिला है जिसमें चार्ट (उपरोक्त पैटर्न में) होना चाहिए:
<Name>Thomas</Name>
इसके बजाय था
<Name></Name>
एक लापता सबट्री के लिए भी यही सच है, आपको यह विचार मिलता है।
बी, सबपर्सिंग विधियों को कॉल करने के बाद, जिन्हें स्टार्ट तत्वों पर कहा जाता है, और संबंधित अंतिम तत्व के बाद रिटर्न करते हैं, अर्थात विधि कॉल (उपरोक्त पैटर्न) से पहले पार्सर एक स्तर से कम है।
ध्यान दें कि यह दृष्टिकोण पूरी तरह से 'आग्नेय' व्हाट्सएप को और अधिक मजबूत कार्यान्वयन के लिए कैसे अनदेखा करता है।
पारसर्स
साथ जाओ Woodstox सबसे सुविधाओं या के लिए Aaalto-एक्सएमएल गति के लिए।