Comment puis-je, étant donné que la mise en œuvre par défaut de W3C DOM (la mise en œuvre par défaut de Java, spécifiquement) modifie l'espace de noms de chaque élément / attribut / noeud dans ce domaz? Efficacement, de préférence. Le DOM ne semble pas avoir une méthode SetNamesPaceuri à ce sujet, ce qui est gênant. P>
J'ai essayé des approches XSL, mais ils n'ont pas réussi à travailler dans les transformateurs JAXP (bien qu'ils travaillent tous bien en Saxon9B, que je ne puisse pas utiliser pour diverses autres raisons). P>
Fondamentalement, j'ai besoin d'une solution pure Core Java qui me permettra de prendre un document et de changer son espace de noms. P>
8 Réponses :
Basé sur mon opinion extrêmement biaisée Ce que vous voulez, ce sera une douleur énorme dans le cul. Je peux voir l'enfer de tablier et de nombreuses boucles recueillies pour faire cela de manière fiable déjà! AHH, la mise en œuvre par défaut de Java, comment je déteste votre NPE: S à Internals, la logique inversée, les étapes supplémentaires nécessaires pour des opérations simples! P>
Alors oui, ma suggestion serait récursive pour les boucles avec la typée de tout type de noeud possible, basée sur mon expérience très personnelle que la mise en œuvre par défaut de Java craint que mal. P>
Je pense que certaines des autres solutions ici sont plus élégantes, mais c'est ce que j'ai fini par faire :)
Ceci n'est pas efficace sur un espace de noms - ajout de DOM. Vous devriez utiliser la méthode Dom Niveau 3 Core Document.renamenode ( Javadoc ) sur chaque élément de descendant dont vous avez voulu changer. (Vous n'auriez normalement pas besoin de changer tant de nœuds d'Attr, car l'espace de nom d'un noeud d'attraps sans préfixe n'est toujours pas nul, plutôt que l'espace de noms de l'élément.) P>
Si tout ce que vous voulez faire est de substituer un espace de noms d'un autre, il peut être plus rapide d'utiliser un espace de noms-ignorant et de modifier simplement l'attribut XMLNS en question. Vous devriez être capable d'obtenir un espace de noms-indemne en définissant le DOMCONFIGARATION ''SPACES ESPACES' à FALSE, mais je n'ai pas essayé ceci en Java et c'est le type d'obscure petite chose DOM IMPS aurait mal. P>
Si l'intention est de changer d'espace de nom, utilisez simplement un éditeur de flux pour modifier NS mappage en URL. P>
Un namspace est plus ou moins une liaison entre le préfixe de l'espace de noms et une URI. Afin de changer rapidement espace de noms, changez simplement la cartographie: p>
Avant: xmlns: myns = "my-nomspace-uri" p>
après: XMLNS: myns = "My-New-Namespace-Uri" P>
Fondamentalement, la cartographie est suffisante, si l'intention est simplement de changer l'espace de noms. De plus, si le document XML a un espace de noms par défaut, la modification de la valeur URL d'espace de noms par défaut changerait l'espace de noms pour l'ensemble du document. P>
Avant: xmlns = "my-nomspace-uri" p>
après: xmlns = "My-New-Namespace-Uri" P>
Bonne idée, mais à ce stade, il nécessiterait de ré-sérialiser dans un flux d'octets et de réexaminer, ce qui n'est pas acceptable d'un point de vue de la performance. J'ai déjà un DOM, que je dois utiliser.
L'espace de noms est modifié sur chaque élément sans préfixe d'espace de noms défini en appliquant un attribut cibleNamespace à votre élément racine. Faire cela nécessitera également de modifier chacun de vos éléments avec un préfixe d'espace de noms. Vous pouvez modifier ce préfixe manuellement ou écrire une logique de script pour parcourir votre arbre Dom pour l'appliquer uniquement si nécessaire. P>
Voici plus de lecture sur l'attribut TargetNamesPace et l'attribut NonamesPaceschema: P>
http: // www .xml.com / pub / A / 2000/11/29 / Schemas / Part1.html? Page = 8 http: //www.computerPoweruer. com / éditorial / article.asp? Article = Articles% 2Farchive% 2FC0407% 2F48C07% 2F48C07.asp P>
Comment puis-je, étant donné que la mise en œuvre par défaut de W3C DOM (la mise en œuvre par défaut de Java, spécifiquement) modifie l'espace de noms de chaque élément / attribut / noeud dans ce domaz? Efficacement, de préférence. P>
Je ne pense pas qu'il existe une solution efficace qui est également robuste. Vous ne pouvez pas simplement renommer quelque chose sur l'élément racine. Considérez ces documents: P>
DOC1 P>
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="urn:fleet" version="1.0"> <xsl:output method="xml" indent="yes" /> <xsl:template match="*"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:apply-templates /> </xsl:copy> </xsl:template> <xsl:template match="f:*"> <xsl:variable name="var.foo" select="local-name()" /> <xsl:element namespace="urn:new" name="{$var.foo}"> <xsl:copy-of select="@*" /> <xsl:apply-templates /> </xsl:element> </xsl:template> </xsl:stylesheet>
C'est ce que j'ai utilisé à l'origine, presque Word-for-Word, mais il s'avère que l'utilisation de notre client de XML est ... primitive. Ou stupide. Vous choisissez. Leurs outils se cassent si le XML n'est pas aménagé i> correctement, pour l'amour de Christ.
Vous pouvez copier votre arbre DOM dans un autre arborescence et faire des modifications pendant le processus. Par exemple, en utilisant org.apache.xml.utils.dombuilder comme implémentation de contenusHandler, vous pouvez remplacer les méthodes de la manière suivantes:
public void startElement(String ns, String localName, String name, Attributes atts) throws SAXException {
super.startElement("new_namespace", localName, name, atts);
}
Si vous êtes d'accord avec l'utilisation des classes XERCES, vous pouvez créer un DOMPARSER qui remplace l'URI des attributs et des éléments avec votre URIS corrigé: l'ailleurs, vous pouvez analyser Un document DOM: P> DOMParse p = new MyDOMParser(...);
p.parse(new InputSource(inputStream));
Document doc = p.getDocument();
Ce code donné qu'un document DOM retournera un nouveau document DOM dans lequel un ensemble donné de traductions d'espace d'espace d'espace de noms a été appliquée (URIMAP). Les clés doivent être l'URIS du document source, les valeurs les URIS de remplacement dans le document de destination. Espace de noms inconnu Uris passe à travers inchangé. Il sait de modifier la valeur des XMLNS: * Attributs, mais ne changera pas d'autres attributs qui pourraient avoir une éventuelle d'espace d'espace de noms comme valeurs (E.g. xsd cibleNamespace)
XSL est probablement la solution la plus facile et devrait fonctionner dans JAXP. Qu'essayez-vous et comment a-t-il échoué?
Dupliqué possible de Java + Dom : Comment définir l'espace de noms de base d'un document (déjà créé)?