كفاءة XSLT خط أنابيب في جافا (أو إعادة توجيه النتائج إلى مصادر)

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

سؤال

لدي سلسلة من XSL 2.0 الأنماط التي تغذي بعضها البعض ، أيالناتج من الأنماط A الأعلاف ب يغذي C.

ما هي الطريقة الأكثر فعالية للقيام بذلك ؟ مسألة إعادة صياغتها هي:كيف يمكن للمرء أن كفاءة الطريق إخراج واحد التحول إلى آخر.

ها هي محاولتي الأولى:

@Override
public void transform(Source data, Result out) throws TransformerException{
    for(Transformer autobot : autobots){
        if(autobots.indexOf(autobot) != (autobots.size()-1)){
            log.debug("Transforming prelim stylesheet...");
            data = transform(autobot,data);
        }else{
            log.debug("Transforming final stylesheet...");
            autobot.transform(data, out);
        }
    }
}

private Source transform(Transformer autobot, Source data) throws TransformerException{
    DOMResult result = new DOMResult();
    autobot.transform(data, result);
    Node node = result.getNode();
    return new DOMSource(node);
}

كما يمكنك أن ترى, أنا باستخدام DOM الجلوس بين التحولات ، على الرغم من أنها مريحة ، انها غير الأداء الأمثل الحكمة.

هل هناك أي طريقة سهلة الطريق القول ، الطريق SAXResult إلى SAXSource?أ ستاكس الحل لن يكون هناك خيار آخر.

أنا على علم من المشاريع مثل XProc, الذي هو بارد جدا إذا لم تكن قد اتخذت نظرة على بعد لكنني لم ترغب في الاستثمار في إطار كله.

هل كانت مفيدة؟

المحلول

لقد وجدت هذا: #3.تسلسل التحولات هذا يدل على اثنين من الطرق لاستخدام TransformerFactory إلى سلسلة من التحولات ، بعد أن النتائج واحدة تحويل الأعلاف القادم تحويل ثم خرج أخيرا من النظام.هذا يتجنب الحاجة إلى وسيط التسلسل إلى سلسلة ملف وما إلى ذلك.بين التحويلات.

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

معظم التحولات على أساس سلسلة من ساكس الأحداث.وهو محلل ساكس عادة تحليل أحد InputStream أو آخر InputSource في ساكس الأحداث ، والتي يمكن بعد ذلك أن بنك الاحتياطي الفيدرالي إلى المحولات.بدلا من الاضطرار محول الإخراج إلى ملف السلسلة ، أو آخر هذه النتيجة ، SAXResult يمكن أن تستخدم بدلا من ذلك.أ SAXResult تقبل ContentHandler ، والتي يمكن تمر هذه ساكس الأحداث مباشرة محول آخر ، إلخ.

هنا هو نهج واحد و أنا واحد عادة ما يفضلون حيث أنه يوفر المزيد المرونة في مختلف المدخلات إخراج المصادر.كما أنه يجعل من من السهل نسبيا لخلق التحول سلسلة حيوي مع متغير عدد من التحولات.

SAXTransformerFactory stf = (SAXTransformerFactory)TransformerFactory.newInstance();

// These templates objects could be reused and obtained from elsewhere.
Templates templates1 = stf.newTemplates(new StreamSource(
  getClass().getResourceAsStream("MyStylesheet1.xslt")));
Templates templates2 = stf.newTemplates(new StreamSource(
  getClass().getResourceAsStream("MyStylesheet1.xslt")));

TransformerHandler th1 = stf.newTransformerHandler(templates1);
TransformerHandler th2 = stf.newTransformerHandler(templates2);

th1.setResult(new SAXResult(th2));
th2.setResult(new StreamResult(System.out));

Transformer t = stf.newTransformer();
t.transform(new StreamSource(System.in), new SAXResult(th1));

// th1 feeds th2, which in turn feeds System.out.

نصائح أخرى

أفضل رهان الخاص بك هو التمسك دوم كما تفعل، لأن معالج XSLT سيضطر إلى إنشاء شجرة على أي حال - البث هو مجرد خيار فئة محدودة للغاية من التحويلات، وعدد قليل إذا كان يمكن لأي معالجات معرفة ذلك تلقائيا والتبديل لتنفيذ التدفق فقط؛ وإلا فإنها مجرد قراءة المدخلات وبناء الشجرة.

سؤال ذي صلة كفاءة XSLT خط أنابيب، مع المعالم، في جافا توضيح على المعلمات الصحيحة تمر إلى سلسلة محولات هذه.

كما قدم تلميحا على حل أقصر قليلا دون محول ثالث:

SAXTransformerFactory stf = (SAXTransformerFactory)TransformerFactory.newInstance();

Templates templates1 = stf.newTemplates(new StreamSource(
        getClass().getResourceAsStream("MyStylesheet1.xslt")));
Templates templates2 = stf.newTemplates(new StreamSource(
        getClass().getResourceAsStream("MyStylesheet2.xslt")));

TransformerHandler th1 = stf.newTransformerHandler(templates1);
TransformerHandler th2 = stf.newTransformerHandler(templates2);

th2.setResult(new StreamResult(System.out));

// Note that indent, etc should be applied to the last transformer in chain:
th2.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");

th1.getTransformer().transform(new StreamSource(System.in), new SAXResult(th2));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top