كيف يمكنك استخدام Java للتعامل مع مستندات XML المختلفة؟

StackOverflow https://stackoverflow.com/questions/30627

  •  09-06-2019
  •  | 
  •  

سؤال

أنا أبحث عن أفضل طريقة لتحليل مستندات XML المتنوعة باستخدام تطبيق Java.أقوم بذلك حاليًا باستخدام SAX ومعالج محتوى مخصص وهو يعمل بشكل رائع - سريع ومستقر.

لقد قررت استكشاف الخيار الذي يحتوي على نفس البرنامج، الذي يتلقى حاليًا مستند XML بتنسيق واحد، ويتلقى تنسيقين إضافيين لمستندات XML، مع تغييرات مختلفة في عناصر XML.كنت أتمنى فقط استبدال ContentHandler بآخر مناسب يعتمد على "startElement" الأول في المستند...ولكن، اه، تم تعيين ContentHandler و ثم تم تحليل الوثيقة!

... constructor ...
{
SAXParserFactory spf = SAXParserFactory.newInstance();

try {
SAXParser sp = spf.newSAXParser();
parser = sp.getXMLReader();
parser.setErrorHandler(new MyErrorHandler());
} catch (Exception e) {} 

... parse StringBuffer ...
try {
parser.setContentHandler(pP);
parser.parse(new InputSource(new StringReader(xml.toString())));
return true;
} catch (IOException e) {
    e.printStackTrace();
} catch (SAXException e) {
    e.printStackTrace();
}
...

لذلك، لا يبدو أنني أستطيع القيام بذلك بالطريقة التي اعتقدت في البداية أنني أستطيع القيام بها.

ومع ذلك، هل أنظر إلى هذا بشكل خاطئ تمامًا؟ما هي أفضل طريقة لتحليل مستندات XML متعددة ومنفصلة بنفس رمز معالجة XML؟ حاولت أن أسأل في مشاركة أكثر عمومية في وقت سابق ...ولكن، أعتقد أنني كنت غامضة للغاية.لأغراض السرعة والكفاءة، لم ألقي نظرة مطلقًا على DOM لأن مستندات XML هذه كبيرة إلى حد ما ويستقبل النظام حوالي 1200 كل بضع دقائق.إنها مجرد طريقة واحدة لإرسال المعلومات

لإطالة هذا السؤال وزيادة حيرتي؛فيما يلي نموذج بالحجم الطبيعي لبعض مستندات XML المتنوعة التي أرغب في الحصول على SAX أو StAX أو ؟؟محلل التعامل بشكل نظيف مع.

المنتجات.xml:

<products>
<product>
  <id>1</id>
  <name>Foo</name>
<product>
  <id>2</id>
  <name>bar</name>
</product>
</products>

متاجر.xml:

<stores>
<store>
  <id>1</id>
  <name>S1A</name>
  <location>CA</location>
</store>
<store>
  <id>2</id>
  <name>A1S</name>
  <location>NY</location>
</store>
</stores>

مديري.xml:

<managers>
<manager>
  <id>1</id>
  <name>Fen</name>
  <store>1</store>
</manager>
<manager>
  <id>2</id>
  <name>Diz</name>
  <store>2</store>
</manager>
</managers>
هل كانت مفيدة؟

المحلول

كما أفهمها، تكمن المشكلة في أنك لا تعرف تنسيق المستند قبل التحليل.يمكنك استخدام نمط المفوض.أفترض أنك لا تقوم بالتحقق من صحة DTD/XSD/etcetera وأنه من المقبول أن يكون لدى DefaultHandler حالة.

public class DelegatingHandler extends DefaultHandler {

    private Map<String, DefaultHandler> saxHandlers;
    private DefaultHandler delegate = null;

    public DelegatingHandler(Map<String, DefaultHandler> delegates) {
        saxHandlers = delegates;
    }

    @Override
    public void startElement(String uri, String localName, String name,
            Attributes attributes) throws SAXException {
       if(delegate == null) {
           delegate = saxHandlers.get(name);
       }
       delegate.startElement(uri, localName, name, attributes);
    }

    @Override
    public void endElement(String uri, String localName, String name)
            throws SAXException {
        delegate.endElement(uri, localName, name);
    }

//etcetera...

نصائح أخرى

لقد قمت بعمل جيد في شرح ما تريد القيام به ولكن ليس السبب.هناك العديد من أطر عمل XML التي تعمل على تبسيط تنظيم وإلغاء تنظيم كائنات Java من/إلى XML.

أبسط هو هضم العموم والتي أستخدمها عادةً لتحليل ملفات التكوين.ولكن إذا كنت تريد التعامل مع كائنات Java فيجب عليك إلقاء نظرة عليها الخروع, JiBX, جاكسب, XMLBeans, XStream, ، أو شيئا من هذا القبيل.Castor أو JiBX هما المفضلان لدي.

لقد حاولت SAXParser مرة واحدة، ولكن مرة واحدة وجدت XStream لم أعود إليها أبدًا.باستخدام XStream، يمكنك إنشاء كائنات Java وتحويلها إلى XML.أرسلهم واستخدم XStream لإعادة إنشاء الكائن.سهل الاستخدام للغاية وسريع وينشئ XML نظيفًا.

وفي كلتا الحالتين عليك أن تعرف البيانات التي ستستقبلها من ملف XML.يمكنك إرسالها بطرق مختلفة لمعرفة المحلل اللغوي الذي ستستخدمه.أو لديك كائن بيانات يمكنه الاحتفاظ بكل شيء ولكن يتم ملء بنية واحدة فقط (المنتج/المتجر/المديرين).ربما شيء مثل:

public class DataStructure {

    List<ProductStructure> products;

    List<StoreStructure> stors;

    List<ManagerStructure> managers;

    ...

    public int getProductCount() {
        return products.lenght();
    }

    ...
}

ومع تحويل XStream إلى XML، قم بإرسال الكائن ثم إعادة إنشائه.ثم افعل بها ما تريد.

انظر الوثائق ل XMLReader.setContentHandler(), ، انها تقول:

قد تقوم التطبيقات بتسجيل معالج جديد أو مختلف في منتصف التحليل، ويجب أن يبدأ محلل SAX في استخدام المعالج الجديد على الفور.

وبالتالي، يجب أن تكون قادرًا على إنشاء ملف SelectorContentHandler الذي يستهلك الأحداث حتى الأول startElement الحدث، بناء على ذلك يغير ContentHandler على قارئ XML، ويمرر حدث عنصر البداية الأول إلى معالج المحتوى الجديد.عليك فقط اجتياز XMLReader إلى SelectorContentHandler في المنشئ.اذا احتجت الجميع الأحداث التي سيتم تمريرها إلى معالج المحتوى الخاص بالمفردات، SelectorContentHandler يجب أن يقوم بتخزين الأحداث مؤقتًا ثم تمريرها، ولكن في معظم الحالات لا يكون ذلك ضروريًا.

في ملاحظة جانبية، لقد استخدمت مؤخرا XOM في جميع مشاريعي تقريبًا للتعامل مع XML، لم يكن الأداء هو المشكلة حتى الآن.

جاكسب.بنية جافا لربط XML.تقوم بشكل أساسي بإنشاء xsd يحدد تخطيط XML الخاص بك (أعتقد أنه يمكنك أيضًا استخدام DTD).ثم تقوم بتمرير XSD إلى برنامج التحويل البرمجي JAXB ويقوم المحول البرمجي بإنشاء فئات Java لتنظيم مستند XML الخاص بك وإلغاء تنظيمه في كائنات Java.انها حقا بسيطة.

راجع للشغل، هناك خيارات سطر الأوامر لjaxb لتحديد اسم الحزمة التي تريد وضع الفئات الناتجة فيها، وما إلى ذلك.

إذا كنت تريد معالجة أكثر ديناميكية، فمن المحتمل أن يعمل نهج Stax بشكل أفضل من Sax.لا يزال هذا مستوى منخفض جدًا؛إذا كنت تريد أسلوبًا أبسط، فإن XStream وJAXB هما المفضلان لدي.لكنها تتطلب كائنات صلبة جدًا لتعيينها.

أتفق مع StaxMan، الذي يريدك بشكل مثير للاهتمام أن تستخدم Stax.إنه محلل يعتمد على السحب بدلاً من الدفع الذي تستخدمه حاليًا.قد يتطلب هذا بعض التغييرات المهمة في التعليمات البرمجية الخاصة بك بالرغم من ذلك.

:-)

نعم، لدي بعض التحيز تجاه Stax.ولكن كما قلت، في كثير من الأحيان يكون ربط البيانات أكثر ملاءمة من حل البث.ولكن إذا كنت ترغب في البث، ولا تحتاج إلى خطوط أنابيب (من مراحل تصفية متعددة)، فإن Stax أبسط من SAX.

شيء اخر:على الرغم من جودة XOM (بدائل WRT)، غالبًا ما لا يكون Tree Model هو الشيء الصحيح الذي يجب استخدامه إذا كنت لا تتعامل مع XML "المرتكز على المستند" (~= صفحات xhtml، وdocbook، ومستندات المكتب المفتوحة).بالنسبة لتبادل البيانات، يعد ربط ملفات التكوين وما إلى ذلك أكثر ملاءمة وأكثر كفاءة وأكثر طبيعية.فقط قل لا للنماذج الشجرية مثل DOM لحالات الاستخدام هذه.لذلك، JAXB، XStream، JibX جيدة.أو، لمزيد من الذوق المكتسب، الهاضم، الخروع، XMLbeans.

يُعرف VTD-XML بأنه أفضل تقنية معالجة XML لمعالجة XML للخدمة الشاقة.انظر المرجع أدناه للحصول على دليل

http://sdiwc.us/digitlib/journal_paper.php?paper=00000582.pdf

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top