Как я могу разделить XML-документ на трети (или, еще лучше, n части)?

В принципе, == сравнивает, если два объекта имеют одну и ту же ссылку в куче, поэтому, если две ссылки не связаны с одним и тем же объектом, это сравнение будет ложным.

equals() - метод унаследованный от класса Object. Этот метод по умолчанию сравнивает, если два объекта имеют одинаковое рефери. Это означает:

object1.equals(object2) & lt; => object1 == object2

Однако, если вы хотите установить равенство между двумя объектами того же класса, вы должны переопределить этот метод. Также очень важно переопределить метод hashCode(), если вы переопределили equals().

Реализация hashCode() при установлении равенства является частью Контракта объектов Java. Если вы работаете с коллекциями, а вы не реализовали hashCode(), могут возникнуть Strange Bad Things:

HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));

null будет напечатано после выполнения предыдущего кода, если вы еще не реализовали hashCode().

7
задан Thomas Owens 11 August 2008 в 15:04
поделиться

10 ответов

Хорошо, конечно, можно всегда извлекать элементы верхнего уровня (является ли это гранулярностью, которую Вы хотите, ваше дело). В C# Вы использовали бы класс XmlDocument. Например, если Ваш XML-файл выглядел примерно так:

<Document>
  <Piece>
     Some text
  </Piece>
  <Piece>
     Some other text
  </Piece>
</Document>

затем Вы использовали бы код как это для извлечения всех Частей:

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

После того как у Вас есть узлы, можно сделать что-то с ними в коде, или можно передать весь текст узла к его собственному XML-документу и действовать на это, как будто это была независимая часть XML (включая сохранение его назад к диску, и т.д.).

3
ответ дан 6 December 2019 в 19:45
поделиться

Парсинг XML-документов с помощью DOM не масштабируется.

Этот сценарий Groovy использует StAX (Потоковый API для XML) для разделения XML-документа между элементами верхнего уровня (который совместно использует тот же QName как первый ребенок корневого документа). Это довольно быстро, обрабатывает произвольные большие документы и очень полезно, когда Вы хотите разделить большой пакетный файл на мелкие кусочки.

Требует Groovy на Java 6 или StAX API и реализации, такой как Woodstox в ПУТИ К КЛАССУ

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()
5
ответ дан 6 December 2019 в 19:45
поделиться

Это - больше комментария, чем ответ, но не было бы:

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

Считать весь файл сразу? Просто мысль, я должен поднять вопрос с тех пор от вида вопроса Thomas, он обеспокоен чтением больших файлов и хочет сломать процесс..

1
ответ дан 6 December 2019 в 19:45
поделиться

Как DannySmurf касается здесь, это - все о структуре xml документа.
Если Вы только два огромных "высокоуровневых" тега, будет чрезвычайно трудно смочь разделить его способом, который позволяет и объединить его назад вместе и считать его часть частью как допустимый xml.

Учитывая документ с большим количеством отдельных частей как те в примере DannySmurfs, это должно быть довольно легко.
Некоторый грубый код в Псевдо C#:

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

// construct the list we need, and fill it with XmlDocuments..
var xmlList = new List<XmlDocument>();
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);
}

Это должно дать Вам n документы с корректным xml и возможностью объединить их назад вместе.
Но снова, это зависит от XML-файла.

3
ответ дан 6 December 2019 в 19:45
поделиться

Это считало бы весь файл сразу. По моему опыту, тем не менее, если Вы просто читаете файл, делая некоторую обработку (т.е. разбивание это) и затем продвигаетесь с Вашей работой, XmlDocument собирается пройти, это, создают/читают/собирают цикл так быстро, что это, вероятно, не будет иметь значения.

Конечно, это зависит от того, каков "большой" файл. Если это будет XML-файл на 30 МБ (который я считал бы большим для XML-файла), то это, вероятно, не будет иметь никакого значения. Если это будет XML-файл на 500 МБ, то использование XmlDocument станет чрезвычайно проблематичным в системах без существенного количества RAM (в этом случае, однако, я утверждал бы, что время для ручного выбора через файл с XmlReader будет более значительным препятствием).

1
ответ дан 6 December 2019 в 19:45
поделиться

Не уверенный, какую обработку Вы делаете, но для очень большого XML, я всегда был поклонником основанной на событии обработки. Возможно, это - мое образование Java, но мне действительно нравится SAX. Необходимо сделать собственное управление состоянием, но после того как Вы заканчиваете это, это - очень эффективный способ парсинга XML.

http://saxdotnet.sourceforge.net/

0
ответ дан 6 December 2019 в 19:45
поделиться

Если у Вас не полностью аллергия на Perl, то XML:: Ветка идет с инструментом, названным xml_split, который может разделить документ, произведя правильно построенный раздел XML. Можно разделить на уровне дерева размером или на выражении XPath.

0
ответ дан 6 December 2019 в 19:45
поделиться

Я собираюсь пойти с youphoric на этом. Для очень больших файлов SAX (или любой другой синтаксический анализатор потоковой передачи) будет большой справкой в обработке. Используя DOM можно собрать просто высокоуровневые узлы, но все еще необходимо проанализировать весь документ, чтобы сделать это... использование синтаксического анализатора потоковой передачи и основанная на событии обработка позволяют Вам "пропустить" узлы, которыми Вы не интересуетесь; делает обработку быстрее.

0
ответ дан 6 December 2019 в 19:45
поделиться

Похоже, что Вы работаете с C# и.NET 3.5. Я столкнулся с некоторыми сообщениями, которые предлагают использовать тип урожая алгоритма на потоке файла с XmlReader.

Вот пара сообщений в блоге для запущения Вас вниз путь:

0
ответ дан 6 December 2019 в 19:45
поделиться

Я сделал видео на YouTube, показывающее , как разделить файлы XML с помощью foxe (бесплатный XML-редактор от Firstobject ), использующий лишь небольшой объем памяти независимо от размера входных и выходных файлов.

Использование памяти для этого считывателя XML CMarkup (анализатор запроса) и Решение для записи XML зависит от размера вложенных документов, которые по отдельности передаются из входного файла в выходные файлы, или от минимального размера блока 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
ответ дан 6 December 2019 в 19:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: