मैं एक एक्सएमएल दस्तावेज़ को तीसरे (या यहां तक ​​कि बेहतर, एन टुकड़े) में कैसे विभाजित कर सकता हूं?

मैं एक ऐसी भाषा का उपयोग करना चाहता हूं जिसे मैं परिचित हूं - जावा, सी #, रूबी, पीएचपी, सी/सी ++, हालांकि किसी भी भाषा या छद्म कोड में उदाहरण स्वागत से अधिक हैं।

एक बड़े एक्सएमएल दस्तावेज़ को छोटे वर्गों में विभाजित करने का सबसे अच्छा तरीका क्या है जो अभी भी वैध एक्सएमएल हैं? मेरे उद्देश्यों के लिए, मुझे उन्हें लगभग तीसरे या चौथे स्थान में विभाजित करने की आवश्यकता है, लेकिन उदाहरण प्रदान करने के लिए, उन्हें एन घटकों में विभाजित करना अच्छा होगा।

0
ro fr bn

8 उत्तर

यह एक उत्तर से अधिक टिप्पणी है, लेकिन यह नहीं होगा:

XmlDocument doc = new XmlDocument();
doc.Load("path");

पूरी फाइल को एक बार में पढ़ें? बस सोचा कि मुझे थॉमस के सवाल के रूप में बिंदु उठाना चाहिए, वह बड़ी फाइलें पढ़ने के बारे में चिंतित है और प्रक्रिया को तोड़ना चाहता है ..

0
जोड़ा

As DannySmurf touches on here, it is all about the structure of the xml document.
If you only two huge "top level" tags, it will be extremely hard to be able to split it in a way that makes it possible to both merge it back together and read it piece by piece as valid xml.

Given a document with a lot of seperate pieces like the ones in DannySmurfs example, it should be fairly easy.
Some rough code in Pseudo C# :

int nrOfPieces = 5;
XmlDocument xmlOriginal = some input parameter..

// construct the list we need, and fill it with XmlDocuments..
var xmlList = new List();
for (int i = 0; i < nrOfPieces ; i++)
{
    var xmlDoc = new XmlDocument();
    xmlDoc.ChildNodes.Add(new XmlNode(xmlOriginal.FistNode.Name));
    xmlList.Add(xmlDoc);
}

var nodeList = xmlOriginal.GetElementsByTagName("Piece")M
// Copy the nodes from the original into the pieces..
for (int i = 0; i < nodeList .Count; i++)
{
    var xmlDoc = xmlList[i % nrOfPieces];
    var nodeToCopy = nodeList[i].Clone();
    xmlDoc.FirstNode.ChildNodes.Add(nodeToCopy);
}

This should give you n docs with correct xml and the possibility to merge them back together.
But again, it depends on the xml file.

0
जोड़ा

यदि आप पर्ल के लिए पूरी तरह से एलर्जी नहीं हैं, तो मॉड्यूल के लिए xml_split जो एक दस्तावेज़ को विभाजित कर सकता है, अच्छी तरह से गठित xml अनुभाग का उत्पादन कर सकता है। आप पेड़ के स्तर पर, आकार या XPath अभिव्यक्ति पर विभाजित कर सकते हैं।

0
जोड़ा

बेशक आप हमेशा शीर्ष-स्तरीय तत्वों को निकाल सकते हैं (चाहे वह ग्रैन्युलरिटी है जो आप चाहते हैं)। सी # में, आप XmlDocument क्लास का उपयोग करेंगे। उदाहरण के लिए, यदि आपकी एक्सएमएल फ़ाइल इस तरह कुछ दिखती है:


  
     Some text
  
  
     Some other text
  

तो आप सभी टुकड़ों को निकालने के लिए इस तरह के कोड का उपयोग करेंगे:

XmlDocument doc = new XmlDocument();
doc.Load("xml file>");
XmlNodeList nl = doc.GetElementsByTagName("Piece");
foreach (XmlNode n in nl)
{
   //Do something with each Piece node
}

एक बार जब आप नोड्स प्राप्त कर लेंगे, तो आप अपने कोड में उनके साथ कुछ कर सकते हैं, या आप नोड के पूरे टेक्स्ट को अपने एक्सएमएल दस्तावेज़ में स्थानांतरित कर सकते हैं और उस पर कार्य कर सकते हैं जैसे कि यह एक्सएमएल का एक स्वतंत्र टुकड़ा था (इसे सहेजने सहित डिस्क पर वापस, आदि)।

0
जोड़ा

यह पूरी फाइल को एक बार में पढ़ेगा। मेरे अनुभव में, यद्यपि, यदि आप केवल फाइल पढ़ रहे हैं, कुछ प्रसंस्करण (यानी इसे तोड़ना) कर रहे हैं और फिर अपने काम के साथ जारी रखते हैं, तो एक्सएमएल डॉक्यूमेंट इसके निर्माण/पढ़ने/एकत्रित चक्र के माध्यम से इतनी जल्दी जा रहा है कि इससे कोई फर्क नहीं पड़ता।

बेशक, यह इस बात पर निर्भर करता है कि "बड़ी" फ़ाइल क्या है। अगर यह 30 एमबी एक्सएमएल फ़ाइल है (जिसे मैं एक एक्सएमएल फ़ाइल के लिए बड़ा मानता हूं), तो शायद यह कोई फर्क नहीं पड़ेगा। यदि यह 500 एमबी एक्सएमएल फ़ाइल है, तो XmlDocument का उपयोग करके सिस्टम पर अत्यधिक मात्रा में रैम के बिना सिस्टम पर बेहद समस्याग्रस्त हो जाएगा (उस स्थिति में, हालांकि, मैं तर्क दूंगा कि XmlReader के साथ फ़ाइल को मैन्युअल रूप से चुनने का समय अधिक महत्वपूर्ण होगा बाधा)।

0
जोड़ा

ऐसा लगता है कि आप सी # और .NET 3.5 के साथ काम कर रहे हैं। मैं कुछ पदों पर आया हूं जो एक एक्सएमएल रीडर के साथ फ़ाइल स्ट्रीम पर उपज प्रकार के एल्गोरिदम का उपयोग करने का सुझाव देते हैं।

पथ शुरू करने के लिए यहां कुछ ब्लॉग पोस्ट दिए गए हैं:

0
जोड़ा

डीओएम का उपयोग कर एक्सएमएल दस्तावेज़ों को पार्स करना स्केल नहीं करता है।

यह ग्रोवी -स्क्रिप्ट शीर्ष-स्तर के बीच xml दस्तावेज़ को विभाजित करने के लिए StAX (XML के लिए स्ट्रीमिंग API) का उपयोग कर रहा है तत्व (जो रूट-दस्तावेज़ के पहले बच्चे के समान QName साझा करते हैं)। यह बहुत तेज है, मनमाने ढंग से बड़े दस्तावेज़ों को संभालता है और जब आप एक बड़ी बैच-फ़ाइल को छोटे टुकड़ों में विभाजित करना चाहते हैं तो बहुत उपयोगी होता है।

जावा 6 या एक स्टेक्स एपीआई पर ग्रोवी की आवश्यकता है और क्लासस्पैट में वुडस्टॉक्स जैसे कार्यान्वयन की आवश्यकता है

import javax.xml.stream.*

pieces = 5
input = "input.xml"
output = "output_%04d.xml"
eventFactory = XMLEventFactory.newInstance()
fileNumber = elementCount = 0

def createEventReader() {
    reader = XMLInputFactory.newInstance().createXMLEventReader(new FileInputStream(input))
    start = reader.next()
    root = reader.nextTag()
    firstChild = reader.nextTag()
    return reader
}

def createNextEventWriter() {
    println "Writing to '${filename = String.format(output, ++fileNumber)}'"
    writer = XMLOutputFactory.newInstance().createXMLEventWriter(new FileOutputStream(filename), start.characterEncodingScheme)
    writer.add(start)
    writer.add(root)
    return writer
}

elements = createEventReader().findAll { it.startElement && it.name == firstChild.name }.size()
println "Splitting ${elements} <${firstChild.name.localPart}> elements into ${pieces} pieces"
chunkSize = elements/pieces
writer = createNextEventWriter()
writer.add(firstChild)
createEventReader().each { 
    if (it.startElement && it.name == firstChild.name) {
        if (++elementCount > chunkSize) {
            writer.add(eventFactory.createEndDocument())
            writer.flush()
            writer = createNextEventWriter()
            elementCount = 0
        }
    }
    writer.add(it)
}
writer.flush()
0
जोड़ा

मैंने एक YouTube वीडियो किया जो xml फ़ाइलों को कैसे विभाजित करें दिखा रहा है foxe (xml संपादक " rel = "nofollow noreferrer"> फर्स्टोबजेक्ट ) इनपुट और आउटपुट फ़ाइलों के आकार के बावजूद केवल स्मृति की एक छोटी राशि का उपयोग कर।

इस सीएमकेआरपी एक्सएमएल रीडर (पुल पार्सर) और एक्सएमएल लेखक समाधान के लिए मेमोरी उपयोग उप-दस्तावेजों के आकार पर निर्भर करता है जिन्हें व्यक्तिगत रूप से इनपुट फाइल से आउटपुट फाइलों में स्थानांतरित किया जाता है, या न्यूनतम 16 केबी ब्लॉक आकार।

split()
{
  CMarkup xmlInput, xmlOutput;
  xmlInput.Open( "50MB.xml", MDF_READFILE );
  int nObjectCount = 0, nFileCount = 0;
  while ( xmlInput.FindElem("//ACT") )
  {
    if ( nObjectCount == 0 )
    {
      ++nFileCount;
      xmlOutput.Open( "piece" + nFileCount + ".xml", MDF_WRITEFILE );
      xmlOutput.AddElem( "root" );
      xmlOutput.IntoElem();
    }
    xmlOutput.AddSubDoc( xmlInput.GetSubDoc() );
    ++nObjectCount;
    if ( nObjectCount == 5 )
    {
      xmlOutput.Close();
      nObjectCount = 0;
    }
  }
  if ( nObjectCount )
    xmlOutput.Close();
  xmlInput.Close();
  return nFileCount;
}
0
जोड़ा