Я использую XSLT для объединения файлов XML. Это позволяет мне настроить операцию слияния, чтобы просто отбросить содержимое вместе или слить на определенном уровне. Это немного больше работы (и синтаксис XSLT является своего рода особенным), но очень гибкий. Несколько вещей, которые вам нужны здесь
а) Включить дополнительный файл
б) Скопировать оригинальный файл 1: 1
c) Создайте свою точку слияния с или без дублирования
а) В начале у меня есть
<xsl:param name="mDocName">yoursecondfile.xml</xsl:param>
<xsl:variable name="mDoc" select="document($mDocName)" />
это позволяет указать на второй файл, используя $ mDoc
б) Инструкции по копированию исходного дерева 1: 1 представляют собой 2 шаблона:
<!-- Copy everything including attributes as default action -->
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:apply-templates select="@*" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>
</xsl:template>
Ничего другого вы получаете 1: 1 копию вашего первого исходного файла. Работает с любым типом XML. Часть слияния зависит от файла. Предположим, у вас есть элементы события с атрибутом идентификатора события. Вы не хотите дублировать идентификаторы. Шаблон будет выглядеть так:
<xsl:template match="events">
<xsl:variable name="allEvents" select="descendant::*" />
<events>
<!-- copies all events from the first file -->
<xsl:apply-templates />
<!-- Merge the new events in. You need to adjust the select clause -->
<xsl:for-each select="$mDoc/logbook/server/events/event">
<xsl:variable name="curID" select="@id" />
<xsl:if test="not ($allEvents[@id=$curID]/@id = $curID)">
<xsl:element name="event">
<xsl:apply-templates select="@*" />
<xsl:apply-templates />
</xsl:element>
</xsl:if>
</xsl:for-each>
</properties>
</xsl:template>
Конечно, вы можете сравнивать другие вещи, такие как имена тегов и т. Д. Также вам решать, насколько глубоко произойдет слияние. Если у вас нет ключа для сравнения, конструкция становится проще, например, для журнала:
<xsl:template match="logs">
<xsl:element name="logs">
<xsl:apply-templates select="@*" />
<xsl:apply-templates />
<xsl:apply-templates select="$mDoc/logbook/server/logs/log" />
</xsl:element>
Для запуска XSLT в Java используйте это:
Source xmlSource = new StreamSource(xmlFile);
Source xsltSource = new StreamSource(xsltFile);
Result xmlResult = new StreamResult(resultFile);
TransformerFactory transFact = TransformerFactory.newInstance();
Transformer trans = transFact.newTransformer(xsltSource);
// Load Parameters if we have any
if (ParameterMap != null) {
for (Entry<String, String> curParam : ParameterMap.entrySet()) {
trans.setParameter(curParam.getKey(), curParam.getValue());
}
}
trans.transform(xmlSource, xmlResult);
или вы загружаете Saxon SAX Parser и делаете это из командной строки (пример оболочки Linux):
#!/bin/bash
notify-send -t 500 -u low -i gtk-dialog-info "Transforming $1 with $2 into $3 ..."
# That's actually the only relevant line below
java -cp saxon9he.jar net.sf.saxon.Transform -t -s:$1 -xsl:$2 -o:$3
notify-send -t 1000 -u low -i gtk-dialog-info "Extraction into $3 done!"
YMMV