2009-10-15 17 views
5

मैं वेब से एचटीएमएल-दस्तावेज़ पर xslt रूपांतरण लागू करने के लिए जावा (6) एक्सएमएल-एपीआई का उपयोग करता हूं। यह दस्तावेज़ xhtml अच्छी तरह से है और इसलिए एक वैध डीटीडी-स्पेक (<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">) शामिल है। अब एक समस्या होती है: एक्सएसएलटी-प्रोसेसर रूपांतरण को बदलने पर डीटीडी डाउनलोड करने का प्रयास करता है और डब्ल्यू 3-सर्वर HTTP 503 त्रुटि से इनकार करता है (Bandwith Limitation के कारण w3)।जावा, एक्सएमएल, एक्सएसएलटी: डीटीडी-सत्यापन को रोकें

मैं एक्सएसएलटी-प्रोसेसर को डीटी डाउनलोड करने से कैसे रोक सकता हूं? मुझे अपने इनपुट-दस्तावेज़ को सत्यापित करने की आवश्यकता नहीं है।

स्रोत है:

import javax.xml.transform.Source; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.transform.stream.StreamSource; 

-

String xslt = "<?xml version=\"1.0\"?>"+ 
    "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"+ 
    " <xsl:output method=\"text\" />"+   
    " <xsl:template match=\"//html/body//div[@id='bodyContent']/p[1]\"> "+ 
    "  <xsl:value-of select=\".\" />"+ 
    "  </xsl:template>"+ 
    "  <xsl:template match=\"text()\" />"+ 
    "</xsl:stylesheet>"; 

    try { 
    Source xmlSource = new StreamSource("http://de.wikipedia.org/wiki/Right_Livelihood_Award"); 
    Source xsltSource = new StreamSource(new StringReader(xslt)); 
    TransformerFactory ft = TransformerFactory.newInstance(); 

    Transformer trans = ft.newTransformer(xsltSource); 

    trans.transform(xmlSource, new StreamResult(System.out)); 
    } 
    catch (Exception e) { 
    e.printStackTrace(); 
    } 

मैं इतने पर यहाँ निम्नलिखित quesitons पढ़ते हैं, लेकिन वे सभी एक और एक्सएमएल-एपीआई का उपयोग करें:

धन्यवाद!

उत्तर

5

उपयोग करने की आवश्यकता मैं हाल ही में इस मुद्दे था, जबकि JAXB का उपयोग कर एक्सएमएल unmarshalling। इसका उत्तर XmlReader और इनपुट स्रोत से SAXSource बनाना था, फिर उसे JAXB UnMarshaller की unmarshal() विधि में पास करें। बाहरी डीटीडी लोड करने से बचने के लिए, मैंने XmlReader पर एक कस्टम EntityResolver सेट किया है।

SAXParserFactory spf = SAXParserFactory.newInstance(); 
SAXParser sp = spf.newSAXParser(); 
XMLReader xmlr = sp.getXMLReader(); 
xmlr.setEntityResolver(new EntityResolver() { 
    public InputSource resolveEntity(String pid, String sid) throws SAXException { 
     if (sid.equals("your remote dtd url here")) 
      return new InputSource(new StringReader("actual contents of remote dtd")); 
     throw new SAXException("unable to resolve remote entity, sid = " + sid); 
    } }); 
SAXSource ss = new SAXSource(xmlr, myInputSource); 

लिखा के रूप में, इस कस्टम इकाई रिसोल्वर एक अपवाद अगर यह कभी एक इकाई एक आप इसे हल करने के लिए चाहते हैं के अलावा अन्य को हल करने के लिए कहा है फेंक देते हैं। यदि आप बस इसे आगे बढ़ना चाहते हैं और रिमोट इकाई लोड करना चाहते हैं, तो "फेंकता" रेखा हटा दें।

+1

बस किसी के पास एक ही समस्या है: यह सही दिशा में जाता है (यही कारण है कि मैंने जवाब स्वीकार किया)। यदि आप डीटीडी वापस नहीं करना चाहते हैं, तो आप एक खाली भी वापस कर सकते हैं। – theomega

+1

कृपया पूंजीकरण को ठीक करें: 'एक्सएमएल रीडर' होना चाहिए 'एक्सएमएल रीडर' – wau

-1

आप javax.xml.parsers.DocumentBuilderFactory

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
factory.setValidating(false); 
DocumentBuilder builder = factory.newDocumentBuilder(); 
InputSource src = new InputSource("http://de.wikipedia.org/wiki/Right_Livelihood_Award") 
Document xmlDocument = builder.parse(src.getByteStream()); 
DOMSource source = new DOMSource(xmlDocument); 
TransformerFactory tf = TransformerFactory.newInstance(); 
Transformer transformer = tf.newTransformer(xsltSource); 
transformer.transform(source, new StreamResult(System.out)); 
+0

उत्तर के लिए धन्यवाद, लेकिन यह कोड वास्तव में एक ही अपवाद फेंकता है: 'java.io.IOException: सर्वर ने HTTP प्रतिक्रिया कोड लौटाया: URL के लिए 503: http: // www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'आपको' src.getByteStream को बदलना होगा() '5 'में' src' को यह काम करने के लिए 'लेकिन' अभी भी एक ही अपवाद है। – theomega

+1

यह कुछ भी नहीं बदलता है। आप स्रोत स्रोत से परिवर्तन के दौरान दस्तावेज़ को पार्स कर सकते हैं, डीओएमसोर्स में परिवर्तन से पहले, लेकिन किसी भी तरह से गायब डीटीडी अपवाद होगा।तो यह "समाधान" कुछ भी हल नहीं करता है, और केवल misleads। – mvmn

3

अपने DocumentBuilderFactory में एक सुविधा सेट करके देखें:

URL url = new URL(urlString); 
InputStream is = url.openStream(); 
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 
DocumentBuilder db; 
db = dbf.newDocumentBuilder(); 
Document result = db.parse(is); 

अभी मैं (2) जब दस्तावेज़ फ़ंक्शन को कॉल बाहरी एक्सएचटीएमएल-पृष्ठों का विश्लेषण करने XSLT के अंदर एक ही समस्याओं का सामना कर रहा हूँ।

0

अगर आप का उपयोग

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 

आप Fllowing कोड के साथ DTD मान्यता को निष्क्रिय करने की कोशिश कर सकते हैं:

dbf.setValidating(false); 
+0

क्रिस से जवाब देखें, यह वही है। – theomega

2

पिछले जवाब मुझे एक समाधान के लिए नेतृत्व किया है, लेकिन मेरे लिए स्पष्ट नहीं था, इसलिए यहां एक पूर्ण है:

private void convert(InputStream xsltInputStream, InputStream srcInputStream, OutputStream destOutputStream) throws SAXException, ParserConfigurationException, 
     TransformerFactoryConfigurationError, TransformerException, IOException { 
    //create a parser with a fake entity resolver to disable DTD download and validation 
    XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); 
    xmlReader.setEntityResolver(new EntityResolver() { 
     public InputSource resolveEntity(String pid, String sid) throws SAXException { 
      return new InputSource(new ByteArrayInputStream(new byte[] {})); 
     } 
    }); 
    //create the transformer 
    Source xsltSource = new StreamSource(xsltInputStream); 
    Transformer transformer = TransformerFactory.newInstance().newTransformer(xsltSource); 
    //create the source for the XML document which uses the reader with fake entity resolver 
    Source xmlSource = new SAXSource(xmlReader, new InputSource(srcInputStream)); 
    transformer.transform(xmlSource, new StreamResult(destOutputStream)); 
} 
संबंधित मुद्दे