J'ai le code suivant
DocumentBuilderFactory dbFactory_ = DocumentBuilderFactory.newInstance();
Document doc_;
DocumentBuilder dBuilder = dbFactory_.newDocumentBuilder();
StringReader reader = new StringReader(s);
InputSource inputSource = new InputSource(reader);
doc_ = dBuilder.parse(inputSource);
doc_.getDocumentElement().normalize();
Alors je peux faire
doc_.getDocumentElement();
et obtenir mon premier élément, mais le problème est qu'au lieu d'être job
, l'élément est tns:job
.
Je connais et ai essayé d'utiliser:
dbFactory_.setNamespaceAware(true);
mais ce n'est tout simplement pas ce que je recherche, j'ai besoin de quelque chose pour me débarrasser complètement des espaces de noms.
Toute aide serait appréciée Merci,
Josh
Pour les nœuds d'élément et d'attribut:
Node node = ...;
String name = node.getLocalName();
vous donnera la partie locale du nom du nœud.
Voir Node.getLocalName ()
Utilisez la fonction Regex. Cela résoudra ce problème:
public static String removeXmlStringNamespaceAndPreamble(String xmlString) {
return xmlString.replaceAll("(<\\?[^<]*\\?>)?", ""). /* remove preamble */
replaceAll("xmlns.*?(\"|\').*?(\"|\')", "") /* remove xmlns declaration */
.replaceAll("(<)(\\w+:)(.*?>)", "$1$3") /* remove opening tag prefix */
.replaceAll("(</)(\\w+:)(.*?>)", "$1$3"); /* remove closing tags prefix */
}
Plutôt que
dbFactory_.setNamespaceAware(true);
Utilisation
dbFactory_.setNamespaceAware(false);
Bien que je sois d’accord avec Tomalak: en général, les espaces de noms sont plus utiles que nuisibles. Pourquoi ne veux-tu pas les utiliser?
Edit: cette réponse ne répond pas à la question du PO, qui était comment se débarrasser de l'espace de nom préfixes . RD01 a fourni la bonne réponse à cette question.
Vous pouvez pré-traiter XML pour supprimer tous les espaces de noms, si vous devez absolument le faire. Je vous le déconseille, car la suppression d'espaces de nom d'un document XML est essentiellement comparable à la suppression d'espaces de nom d'un cadre de programmation ou d'une bibliothèque: vous risqueriez des conflits de noms et vous perdriez la possibilité de différencier des éléments uniques. Cependant, ce sont vos funérailles. ;-)
Cette transformation XSLT supprime tous les espaces de nom de tout document XML.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:apply-templates select="node()|@*" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Appliquez-le à votre document XML. Les exemples de Java pour faire une telle chose devraient être nombreux, même sur ce site. Le document résultant sera exactement de la même structure et de la même présentation, sans espaces de noms.
public static void wipeRootNamespaces(Document xml) {
Node root = xml.getDocumentElement();
NodeList rootchildren = root.getChildNodes();
Element newroot = xml.createElement(root.getNodeName());
for (int i=0;i<rootchildren.getLength();i++) {
newroot.appendChild(rootchildren.item(i).cloneNode(true));
}
xml.replaceChild(newroot, root);
}
La taille du fichier XML d'entrée doit également être prise en compte lors du choix de la solution. Pour les fichiers xml volumineux, d'une taille d'environ 100 Ko, si votre entrée provient d'un service Web, vous devez également prendre en compte les implications de la récupération de place lorsque vous manipulez une chaîne volumineuse. Nous avions déjà utilisé String.replaceAll auparavant, ce qui entraînait de fréquentes MOO en production avec une taille de segment de mémoire de 1,5 G en raison de la façon dont replaceAll était implémenté.
Vous pouvez consulter http://app-inf.blogspot.com/2013/04/pitfalls-of-handling-large-string.html pour nos résultats.
Je ne suis pas sûr de savoir comment XSLT traite les grands objets String, mais nous avons fini par analyser la chaîne manuellement pour supprimer les préfixes en une analyse afin d'éviter de créer d'autres objets Java volumineux.
public static String removePrefixes(String input1) {
String ret = null;
int strStart = 0;
boolean finished = false;
if (input1 != null) {
//BE CAREFUL : allocate enough size for StringBuffer to avoid expansion
StringBuffer sb = new StringBuffer(input1.length());
while (!finished) {
int start = input1.indexOf('<', strStart);
int end = input1.indexOf('>', strStart);
if (start != -1 && end != -1) {
// Appending anything before '<', including '<'
sb.append(input1, strStart, start + 1);
String tag = input1.substring(start + 1, end);
if (tag.charAt(0) == '/') {
// Appending '/' if it is "</"
sb.append('/');
tag = tag.substring(1);
}
int colon = tag.indexOf(':');
int space = tag.indexOf(' ');
if (colon != -1 && (space == -1 || colon < space)) {
tag = tag.substring(colon + 1);
}
// Appending tag with prefix removed, and ">"
sb.append(tag).append('>');
strStart = end + 1;
} else {
finished = true;
}
}
//BE CAREFUL : use new String(sb) instead of sb.toString for large Strings
ret = new String(sb);
}
return ret;
}
Tomalak, un correctif de votre XSLT (dans le 3ème modèle):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node() | @*" />
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<!-- Here! -->
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Au lieu d'utiliser TransformerFactory et ensuite d'appeler transform sur celui-ci (qui injectait l'espace de nom vide, j'ai transformé comme suit:
OutputStream outputStream = new FileOutputStream(new File(xMLFilePath));
OutputFormat outputFormat = new OutputFormat(doc, "UTF-8", true);
outputFormat.setOmitComments(true);
outputFormat.setLineWidth(0);
XMLSerializer serializer = new XMLSerializer(outputStream, outputFormat);
serializer.serialize(doc);
outputStream.close();