Fusionnez deux fichiers XML en Java
J'ai deux fichiers XML de structure similaire qui je souhaite fusionner en un seul fichier.
Actuellement, je suis en utilisant EL4J XML de Fusion qui je suis tombé sur ce tutoriel.
Cependant, il ne fusionne pas comme prévu pour les instances, le principal problème est son pas de fusionner les deux fichiers en un seul élément aka celui qui contient 1, 2, 3 et 4.
Au lieu de cela, il écarte tout simplement 1 et 2 ou 3 et 4 en fonction du fichier est fusionnée la première.
Donc je serais reconnaissant à toute personne qui a de l'expérience avec XML Fusion si ils pouvaient me dire ce que je fais mal ou sinon est-ce quelqu'un connais un bon d'API XML pour Java qui serait capable de fusionner les fichiers que j'ai besoin?
Merci beaucoup pour Votre Aide à l'Avance
Edit:
Pourrait faire avec quelques bonnes suggestions sur cette ajouté une prime. J'ai essayé jdigital de la suggestion, mais encore d'avoir des problèmes avec XML de fusion.
Ci-dessous est un exemple du type de structure de fichiers XML que je suis en train de fusionner.
<run xmloutputversion="1.02">
<info type="a" />
<debugging level="0" />
<host starttime="1237144741" endtime="1237144751">
<status state="up" reason="somereason"/>
<something avalue="test" test="alpha" />
<target>
<system name="computer" />
</target>
<results>
<result id="1">
<state value="test" />
<service value="gamma" />
</result>
<result id="2">
<state value="test4" />
<service value="gamma4" />
</result>
</results>
<times something="0" />
</host>
<runstats>
<finished time="1237144751" timestr="Sun Mar 15 19:19:11 2009"/>
<result total="0" />
</runstats>
</run>
<run xmloutputversion="1.02">
<info type="b" />
<debugging level="0" />
<host starttime="1237144741" endtime="1237144751">
<status state="down" reason="somereason"/>
<something avalue="test" test="alpha" />
<target>
<system name="computer" />
</target>
<results>
<result id="3">
<state value="testagain" />
<service value="gamma2" />
</result>
<result id="4">
<state value="testagain4" />
<service value="gamma4" />
</result>
</results>
<times something="0" />
</host>
<runstats>
<finished time="1237144751" timestr="Sun Mar 15 19:19:11 2009"/>
<result total="0" />
</runstats>
</run>
Sortie attendue
<run xmloutputversion="1.02">
<info type="a" />
<debugging level="0" />
<host starttime="1237144741" endtime="1237144751">
<status state="down" reason="somereason"/>
<status state="up" reason="somereason"/>
<something avalue="test" test="alpha" />
<target>
<system name="computer" />
</target>
<results>
<result id="1">
<state value="test" />
<service value="gamma" />
</result>
<result id="2">
<state value="test4" />
<service value="gamma4" />
</result>
<result id="3">
<state value="testagain" />
<service value="gamma2" />
</result>
<result id="4">
<state value="testagain4" />
<service value="gamma4" />
</result>
</results>
<times something="0" />
</host>
<runstats>
<finished time="1237144751" timestr="Sun Mar 15 19:19:11 2009"/>
<result total="0" />
</runstats>
</run>
source d'informationauteur Mark Davidson
Vous devez vous connecter pour publier un commentaire.
Pas très élégant, mais vous pouvez le faire avec le DOM et l'analyseur de XPath:
Cela suppose que vous pouvez vous tenir au moins deux des documents en mémoire simultanément.
- Je utiliser XSLT pour fusionner des fichiers XML. Cela me permet d'ajuster l'opération de fusion de il suffit de claquer le contenu de l'ensemble ou de fusion à un niveau spécifique. C'est un peu plus de travail (et de la syntaxe XSLT est une sorte de spéciale) mais super flexible. Quelques choses que vous devez ici
a) d'Inclure un fichier supplémentaire
b) une Copie du fichier d'origine 1:1
c) la Conception de votre point de fusion, avec ou sans duplication d'évitement
a) au début, j'ai
cela permet de pointer à la deuxième fichier à l'aide de $mDoc
b) Les instructions pour copier une arborescence source 1:1 sont 2 modèles:
Avec rien d'autre que vous obtenez une copie 1:1 de votre premier fichier source. Fonctionne avec n'importe quel type de données XML. La fusion de la partie est de fichier spécifique. Nous allons présumer que vous avez de l'événement éléments avec un événement de l'attribut ID. Vous ne voulez pas d'Id en double. Le modèle devrait ressembler à ceci:
Bien sûr, vous pouvez comparer d'autres choses comme les noms de balises etc. Aussi c'est à vous de la profondeur de la fusion se passe. Si vous n'avez pas de clé pour comparer, la construction devient plus facile par exemple pour le journal:
Pour exécuter XSLT en Java utiliser ceci:
ou de télécharger le Saxon Analyseur SAX et le faire à partir de la ligne de commande (shell Linux exemple):
YMMV
Merci à tous pour leurs suggestions, malheureusement, aucune des méthodes proposées s'est avéré être adapté à la fin, comme j'avais besoin d'avoir des règles pour la façon dont les différents nœuds de la structure où mereged.
Donc ce que j'ai fait est de prendre le DTD concernant les fichiers XML, j'ai été de fusionner et de créer un certain nombre de classes qui reflètent la structure.
À partir de cela, j'ai utilisé XStream à unserialize le fichier XML de retour dans les classes.
De cette façon, je annoté mes classes en faire un processus d'utilisation d'une combinaison de règles affectées avec des annotations et un peu de réflexion en vue de la fusion des Objets, par opposition à la fusion de l'effectif de la structure XML.
Si quelqu'un est intéressé, dans le code que dans ce cas fusionne Nmap fichiers XML veuillez voir http://fluxnetworks.co.uk/NmapXMLMerge.tar.gz les codes qui ne sont pas parfait et je vous avoue ne pas massivement souple, mais cela fonctionne bien. J'ai l'intention de remettre sur pied le système avec l'analyse de la DTD automatiquement quand j'ai du temps libre.
C'est comment il devrait ressembler à l'aide de XML de Fusion:
Vous devez définir l'ID de matcher pour //le résultat de nœud et de définir les PRÉSERVER de l'action de //info nœud. Méfiez-vous également que .propriétés XML de Fusion utilise sont sensibles à la casse - vous devez utiliser le "xpath" pas "XPath" dans votre .les propriétés.
N'oubliez pas de définir la configuration de paramètre comme ceci:
Il pourrait aider si vous avez été explicite sur le résultat que vous êtes intéressé par la réalisation. Est-ce que vous me demandez?
Doc A:
Doc B:
Résultat Fusionné:
Êtes-vous inquiet au sujet de mise à l'échelle pour les documents de grande taille?
La façon la plus simple à mettre en Java est d'utiliser un flux XML parser (google pour "java StAX'). Si vous utilisez le javax.xml.flux de bibliothèque, vous trouverez que la XMLEventWriter a une méthode pratique XMLEventWriter#ajouter(XMLEvent). Tout ce que vous avez à faire est de la boucle sur les éléments de niveau supérieur dans chaque document et de les ajouter à votre écrivain à l'aide de cette méthode pour générer votre résultat fusionné. La seule funky partie est mise en œuvre, le lecteur logique qui considère uniquement (seuls les appels 'ajouter') sur les nœuds de niveau supérieur.
J'ai récemment mis en œuvre cette méthode si vous avez besoin de conseils.
J'ai pris un coup d'oeil au lien référencé; c'est bizarre que XMLMerge ne fonctionnerait pas comme prévu. Votre exemple me semble simple. Avez-vous lu la section intitulée À l'aide de XPath déclarations XmlMerge? À l'aide de l'exemple, essayez de mettre en place un XPath sur les résultats et de définir à fusionner. Si je suis en train de lire la doc correctement, il devrait ressembler à quelque chose comme ceci:
Vous pourriez être en mesure d'écrire une application java qui deserilizes les documents XML en objets, puis "fusionner" les objets individuels par programmation dans une collection. Ensuite, vous pouvez sérialiser l'objet de collection, de les renvoyer à un fichier XML avec tout "de la fusion."
La JAXB API a certains outils permettent de convertir un document XML et le schéma dans les classes java. Le "xjc" outil pourrait être en mesure de le faire, bien que je ne me souviens pas si vous pouvez créer des classes directement à partir du document XML, ou si vous devez générer un schéma d'abord. Il existe des outils que peut générer un schéma à partir d'un document XML.
Espère que cela aide... ne sais pas si c'est ce que vous cherchez.
En plus de l'utilisation de Stax (ce qui est logique), il serait probablement plus facile avec StaxMate (http://staxmate.codehaus.org/Tutorial). Il suffit de créer 2 SMInputCursors, et de l'enfant curseur en cas de besoin. Et puis typique de fusion de tri avec 2 curseurs. Similaire au parcours des DOM documents récursive de la descente.
Donc, vous êtes uniquement intéressé par la fusion de la "résultats" éléments? Tout le reste est ignoré? Le fait que input0 a un <info type=""/> et input1 a un <info type="b"/> et le résultat attendu a un <info type=""/> semble le suggérer.
Si vous n'êtes pas inquiet au sujet de mise à l'échelle et vous voulez résoudre ce problème rapidement, alors je suggère la rédaction d'un problème spécifique à la partie du code qui utilise une simple bibliothèque comme JDOM à considérer les entrées et écrire le résultat de sortie.
Tentative d'écriture d'un outil générique qui a été "intelligent" de la assez pour gérer l'ensemble de la possible fusion des cas, il serait assez de temps que vous avez à exposer une possibilité de configuration pour définir les règles de combinaison. Si vous savez exactement ce que vos données vont ressembler et vous savez exactement comment la fusion doit être exécutée alors j'imagine que votre algorithme à pied chaque entrée XML et d'écrire sur une seule sortie XML.
Vous pouvez essayer Dom4J qui offre un très bon moyen pour extraire des informations à l'aide de Requêtes XPath et vous permet également d'écrire du XML très facilement. Vous avez juste besoin de jouer avec l'API pendant un certain temps pour faire votre travail
Avez-vous considéré comme juste, pas la peine avec l'analyse du XML "correctement" et traiter les fichiers que les grandes chaînes longues et à l'aide ennuyeux vieux trucs tels que des cartes de hachage et des expressions régulières...? Cela pourrait être l'un de ces cas où la fantaisie des acronymes avec X dans leur juste faire le travail fiddlier qu'il doit être.
Évidemment, cela ne dépendre un peu de la quantité de données que vous avez réellement besoin d'analyser tout en faisant de la fusion. Mais par le son des choses, la réponse n'est pas beaucoup.