Я вижу довольно много сообщений/блогов/статей о разделении XML файла на более мелкие куски и решил создать свой собственный, потому что у меня есть некоторые пользовательские требования. Вот что я имею в виду, рассмотрим следующий XML:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<company>
<staff id="1">
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<nickname>mkyong</nickname>
<salary>100000</salary>
</staff>
<staff id="2">
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<nickname>mkyong</nickname>
<salary>100000</salary>
</staff>
<staff id="3">
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<nickname>mkyong</nickname>
<salary>100000</salary>
</staff>
<staff id="4">
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<nickname>mkyong</nickname>
<salary>100000</salary>
</staff>
<staff id="5">
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<salary>100000</salary>
</staff>
</company>
Я хочу разбить этот xml на n частей, каждый из которых содержит 1 файл, но элемент staff
должен содержать nickname
, если он там не нужен. Таким образом, это должно приводить к 4 слотам xml, каждый из которых содержит идентификатор персонала, начиная с 1 до 4.
Вот мой код:
public int split() throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(inputFilePath)));
String line;
List<String> tempList = null;
while((line=br.readLine())!=null){
if(line.contains("<?xml version=\"1.0\"") || line.contains("<" + rootElement + ">") || line.contains("</" + rootElement + ">")){
continue;
}
if(line.contains("<"+ element +">")){
tempList = new ArrayList<String>();
}
tempList.add(line);
if(line.contains("</"+ element +">")){
if(hasConditions(tempList)){
writeToSplitFile(tempList);
writtenObjectCounter++;
totalCounter++;
}
}
if(writtenObjectCounter == itemsPerFile){
writtenObjectCounter = 0;
fileCounter++;
tempList.clear();
}
}
if(tempList.size() != 0){
writeClosingRootElement();
}
return totalCounter;
}
private void writeToSplitFile(List<String> itemList) throws Exception{
BufferedWriter wr = new BufferedWriter(new FileWriter(outputDirectory + File.separator + "split_" + fileCounter + ".xml", true));
if(writtenObjectCounter == 0){
wr.write("<" + rootElement + ">");
wr.write("\n");
}
for (String string : itemList) {
wr.write(string);
wr.write("\n");
}
if(writtenObjectCounter == itemsPerFile-1)
wr.write("</" + rootElement + ">");
wr.close();
}
private void writeClosingRootElement() throws Exception{
BufferedWriter wr = new BufferedWriter(new FileWriter(outputDirectory + File.separator + "split_" + fileCounter + ".xml", true));
wr.write("</" + rootElement + ">");
wr.close();
}
private boolean hasConditions(List<String> list){
int matchList = 0;
for (String condition : conditionList) {
for (String string : list) {
if(string.contains(condition)){
matchList++;
}
}
}
if(matchList >= conditionList.size()){
return true;
}
return false;
}
Я знаю этот поток открытия/закрытия для каждого записанного элемента staff
, который влияет на производительность. Но если я пишу один раз за файл (который может содержать n число staff
). Естественно, элементы root и split настраиваются.
Любые идеи, как я могу улучшить производительность/логику? Я бы предпочел какой-то код, но хороший совет может быть лучше иногда
Edit:
Этот XML-пример на самом деле является фиктивным примером: реальный XML, который я пытаюсь разбить, составляет около 300-500 различных элементов под разделенным элементом, все из которых появляются в случайном порядке, а число меняется. Stax может быть не лучшим решением?
Обновление Bounty:
Я ищу решение (код), которое будет:
-
Уметь разделить XML файл на n частей с помощью x разделенных элементов (из фиктивного примера примера XML является разделенный элемент).
-
Содержимое спрятанных файлов должно быть обернуто в корневой элемент из исходного файла (например, в компании-образцовом примере)
-
Я хотел бы иметь возможность указать условие, которое должно быть в разделенном элементе, то есть я хочу только сотрудников, у которых есть псевдоним, я хочу отказаться от тех, у кого нет псевдонимов. Но уметь также разделить без условий во время раскола без условий.
-
Код не обязательно должен улучшить мое решение (отсутствие хорошей логики и производительности), но оно работает.
И не доволен "но он работает". И я не могу найти достаточно примеров Stax для таких операций, сообщество пользователей также не очень велико. Это также не должно быть решение Stax.
Я, наверное, слишком много задаю, но я здесь, чтобы научиться чему-то, давая хорошую щедрость для решения, которое я думаю.