मेरी समस्या: मैं बड़ी मात्रा में बड़ी एक्सएमएल फाइलों को पार्स करना चाहता हूं और डेटा को MySQL डेटाबेस में लिखना चाहता हूं। बात यह है कि, वे सभी एक्सएमएल फाइलें अच्छी तरह से गठित नहीं हैं, क्योंकि प्राधिकरण कई एक्सएमएल फाइलों को एक एक्सएमएल फाइल में मर्ज करता है और उन्हें प्रकाशित करता है। तो मेरा सैक्स पार्सर एकल एक्सएमएल फाइलों के लिए पूरी तरह से काम करता है, एक त्रुटि फेंकता है, वह एक एक्सएमएल फाइल को संभाल नहीं सकता है, जिसमें एकाधिक एक्सएमएल घोषणाएं (एक्सएमएल-संस्करण ...)

फेंका गया त्रुटि संदेश:

थ्रेड में अपवाद "मुख्य" org.xml.sax.SAXParseException; systemId: ..... "[xX][mM][lL]" .....

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE us-patent-grant SYSTEM "us-patent-grant-v42-2006-08-23.dtd" [ ]>
<us-patent-grant lang="EN" dtd-version="v4.2 2006-08-23" file="USD0535456-20070123.XML" status="PRODUCTION" id="us-patent-grant" country="US" date-produced="20070110" date-publ="20070123">
<us-bibliographic-data-grant>
<publication-reference>
<document-id>
<country>US</country>
<doc-number>D0535456</doc-number>
<kind>S1</kind>
<date>20070123</date>
</document-id>
</publication-reference>
<us-application-series-code>29</us-application-series-code>
</us-bibliographic-data-grant>
</us-patent-grant>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE us-patent-grant SYSTEM "us-patent-grant-v42-2006-08-23.dtd" [ ]>
<us-patent-grant lang="EN" dtd-version="v4.2 2006-08-23" file="USD0535457-20070123.XML" status="PRODUCTION" id="us-patent-grant" country="US" date-produced="20070110" date-publ="20070123">
<us-bibliographic-data-grant>
...

चूंकि मैं कई मंचों और वेबसाइटों में देख रहा था, एक्सएमएल फ़ाइल को पढ़ने के लिए एकमात्र शांत समाधान इसे रूट टैग पर विभाजित करना और इसे अलग एक्सएमएल फाइलों में लिखना है? मैं किसी xml फ़ाइल को SAX / Stax / DOM से पार्स किए बिना कैसे पढ़ और लिख सकता हूँ?

परिणाम होना चाहिए: एक्सएमएल फ़ाइल 1:

?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE us-patent-grant SYSTEM "us-patent-grant-v42-2006-08-23.dtd" [ ]>
<us-patent-grant lang="EN" dtd-version="v4.2 2006-08-23" file="USD0535456-20070123.XML" status="PRODUCTION" id="us-patent-grant" country="US" date-produced="20070110" date-publ="20070123">
<us-bibliographic-data-grant>
...
</us-bibliographic-data-grant>
</us-patent-grant>

एक्सएमएल फ़ाइल 2:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE us-patent-grant SYSTEM "us-patent-grant-v42-2006-08-23.dtd" [ ]>
<us-patent-grant lang="EN" dtd-version="v4.2 2006-08-23" file="USD0535457-20070123.XML" status="PRODUCTION" id="us-patent-grant" country="US" date-produced="20070110" date-publ="20070123">
<us-bibliographic-data-grant>
...
0
Burner08 27 जिंदा 2019, 13:31

1 उत्तर

सबसे बढ़िया उत्तर

चूंकि आपकी फ़ाइल में कई xml दस्तावेज़ हैं, यह वास्तव में एक xml फ़ाइल नहीं है। यह सिर्फ एक फाइल है। तो आप इसे किसी भी चीज़ के साथ पढ़ सकते हैं जिसे आप फ़ाइलों को पढ़ना पसंद करते हैं (उदाहरण के लिए एक फ़ाइल रीडर)।

एक अन्य विकल्प पाठक या स्ट्रीम का विस्तार करना और एक नई कक्षा बनाना होगा जो एकाधिक एक्सएमएल दस्तावेज़ों वाली फाइलों को संभालता है। इसकी आवश्यकता होगी:

  • एक नया xml दस्तावेज़ मिलने पर फ़ाइल का अंत लौटाएं, यह पार्सर को बताएगा कि यह वर्तमान दस्तावेज़ के साथ किया गया है
  • फ़ाइल के छद्म अंत के बाद पढ़ने की अनुमति दें ताकि अगला xml दस्तावेज़ पढ़ा जा सके
  • हैंडल बंद करें ताकि यह केवल तभी बंद हो जब पूरी फ़ाइल पढ़ी जाए, हो सकता है कि किसी प्रकार के बल को बंद करने का विकल्प भी हो

Contoh berikut menunjukkan cara menjadwalkan pemberitahuan lokal yang akan dipicu setiap hari, 60 detik dari sekarang.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;

public class ConcatenatedXmlReader extends BufferedReader {

    private String nextLine = "";

    public ConcatenatedXmlReader(Reader reader, int size) {
        super(reader, size);
    }

    public ConcatenatedXmlReader(Reader reader) {
        super(reader);
    }

    private boolean seenXmlStart = false;

    // which method you need to override probably depends on which sax parser you use
    @Override
    public int read(char[] buffer, int offset, int length) throws IOException {
        readNextLine();
        if (nextLine == null) {
            return -1;
        }
        if (nextLine.startsWith("<?xml")) {
            if (seenXmlStart) {
                return -1;
            }
            seenXmlStart = true;
        }
        int addToBuffer = Math.min(nextLine.length(), length);
        for (int i = 0; i < addToBuffer; i++) {
            buffer[i] = nextLine.charAt(i);
        }
        nextLine = (addToBuffer < nextLine.length()) ? nextLine.substring(addToBuffer) : "";
        return addToBuffer;
    }

    public boolean hasXmlDocuments() throws IOException {
        readNextLine();
        seenXmlStart = false;
        return nextLine != null &&  nextLine.length() > 0;
    }

    private void readNextLine() throws IOException {
        if (nextLine != null && nextLine.length() == 0) {
            nextLine = readLine();
        }
    }

    @Override
    public void close() throws IOException {
        // override so it doesn't close the file when there are still more xml documents.
        if (nextLine != null) {
            return;
        }
        super.close();
    }

} 

फ़ाइल में अधिक xml दस्तावेज़ होने पर आप सैक्स पार्सर को कई बार कॉल करेंगे।

जैसे

        SAXParserFactory factory = SAXParserFactory.newInstance();
        MyHandler handler = new MyHandler();
        ConcatenatedXmlReader reader = new ConcatenatedXmlReader(new FileReader(inputFile));
        SAXParser saxParser = factory.newSAXParser();
        while (reader.hasXmlDocuments()) {
            saxParser.parse(new InputSource(reader), handler);
        }
0
pcoates 27 जिंदा 2019, 20:02