[Open XML] Travailler avec Open XML : Linq To XML (Partie 1 - Namespace)
Vous vous doutez bien que l’on ne peut oublier un tel outil pour manipuler des documents Open XML : Linq to XML. En effet si tous les outils que je vous ai présenté jusqu’à présent (et que je vais continuer à vous présenter) sont utiles, on ne peut les comparer à la productivité que vous donne Linq To XML. Au delà de vous présenter le pourquoi du comment XLinq ou Linq to XML, voici un petit tutorial rapide sur son utilisation avec quelques cas en fin de post pour Open XML.
Tout d’abord, n’oubliez pas l’indispensable import : using System.Xml.Linq;
Créer un document avec un namespace …
XNamespace wygwam = "http://www.wygwam.com";
XElement root = new XElement(wygwam + "Entreprise",
new XElement(wygwam + "Nom", "Wygwam"));
Le résultat :
Très bien, maintenant vous savez comment créer une structure avec un espace de noms par défaut et spécifier celui-ci à des éléments, mais vous ne savez pas encore comment faire pour spécifier le préfixe de l’espace de nom. En effet, Linq to XML crée l’attribut avec l’espace de nom par défaut car il n’en existe pas d’autre et que c’est l’espace de nom par défaut.
Voici la façon de spécifier un espace de nom avec préfixe à la structure XML, et vous vous en rendrez compte, on pourrait penser que XLinq n’a pas été conçu pour les espace de noms (néanmoins détrompez vous en !). En effet, vous devrez vous même les déclarer dans la structure !
L’exemple suivant présente deux intérêts : comment ajouter un élément/attribut et un espace de nom avec préfixe :
XNamespace wygwam = "http://www.wygwam.com";
XElement root = new XElement(wygwam + "Entreprise",
new XAttribute(XNamespace.Xmlns + "wygwam", wygwam.NamespaceName),
new XElement(wygwam + "Nom", "Wygwam"));
Le résultat :
Remarque : gardez bien cet exemple en tête, ses concepts nous serviront pour les requêtes XPath, lesquelles font très attention aux espaces de noms même s’il n’y a aucun préfixe devant …
Maintenant voici comment spécifier deux espaces (un par défaut de nom au sein d’une même structure XML) :
XNamespace microsoft = "http://www.microsoft.com";
XNamespace wygwam = "http://www.wygwam.com";
XElement root = new XElement(microsoft + "Entreprises",
new XAttribute("xmlns", microsoft.NamespaceName),
new XAttribute(XNamespace.Xmlns + "wygwam", wygwam.NamespaceName),
new XElement(microsoft + "Entreprise",
new XElement(wygwam + "Nom", "Wygwam")));
Le résultat :
Si vous voulez préfixer tous les espaces de noms (comme beaucoup de structure Open XML) spécifiez simplement les deux espaces de noms en utilisant XNamespace.Xmlns + <préfixe NS>.
Il existe une autre façon (assez inutile de faire cela, malgré que ce soit comme ça que j’ai commencé à écrire ma première structure XML, avant de comprendre le fonctionnement des espaces de noms des attributs avec XNamespace.Xmlns + <préfixe NS>) c’est en utilisant un XName sous la forme {<nom de l’espace de nom}<nom élement/attribut>. Par exemple : {http://www.wygwam.com}Nom. Néanmoins, comme on s’en doute - merci Reflector – cela prendre du temps à parser et sur des documents Open XML de 30 Mo de texte, les performances s’en ressentent (je m’en suis vite rendu compte …). Vous rencontrerez souvent ces noms complets lorsque vous deboguerez votre code avec des structures contenant de multiple espace de noms.
Exemple Open XML avec le SDK Open XML
Et si je vous disais que seulement quelques lignes suffisent à créer un document Word (si si il s’ouvre dans Word 2007 sans problème) ? Pff diront certains, pourtant :
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Create("MonDoc.docx", WordprocessingDocumentType.Document))
{
// On ajoute la partie principale
MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
// Création de la structure XML WordprocessingML
XNamespace wNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XDocument xmlDoc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement(wNamespace + "document",
new XElement(wNamespace + "body",
new XElement(wNamespace + "p",
new XElement(wNamespace + "r",
new XElement(wNamespace + "t",
new XText("Hello Open XML")))))));
xmlDoc.Save(new StreamWriter(mainPart.GetStream()));
}
En remerciant le SDK Open XML v1 et XLinq … XPath et requêtes dans la prochaine partie.
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :