Auslesen und Schreiben von Custom XML mit dem Open XML SDK

Das Open XML SDK (verfügbar als CTP seit Juni letzen Jahres) macht es wesentlich einfacher, mit den Bestandteilen eines Open XML Dokumentes umzugehen. Implementiert sind die durch die Open Packaging Conventions abgedeckten Teile, also noch nicht die XML Dokumente, die z.B. WordProcessingML beinhalten. Das wird hoffentlich irgendwann kommen. Zumindest brauchen wir uns damit aber nicht mehr mit Content Types und Relationships enthalteneden XML Dateien herumzuschlagen.

Haben Sie beispielsweise Custom XML Parts und wollen das XML von da abholen bzw. schreiben, so gibt es jetzt ein Objektmodell dafür. Bei mehreren Custom XML Parts sollten allerdings eigene Namespaces vergeben, um die einzelnen Parts auseinander zu halten. Ein solcher Store könnte z.B. so aussehen:

<AddressStore xmlns="**https://www.contoso.com/CRM/AddressStore**"\>

    <Address>

 <FullName></FullName>

       <Street></Street>

       <ZipCode></ZipCode>

 <City></City>

       <Phone></Phone>

</Address>

</AddressStore>

 

Dann könnte mit folgendem Code der Part ausgelesen werden, wobei ein sauberes XML Dokument zurückgeliefert wird: 

 

private XmlDocument ReturnCustomXML(string FName, string schema)

{

using (WordprocessingDocument wDoc = WordprocessingDocument.Open(FName, false))

{

MainDocumentPart mainPart = wDoc.MainDocumentPart;

foreach (CustomXmlPart custXML in mainPart.CustomXmlParts)

{

XmlDocument xDocCustomXML = new XmlDocument();

xDocCustomXML.Load(custXML.GetStream(FileMode.Open));

XmlNode xn = xDocCustomXML.FirstChild;

if (!xn.HasChildNodes) xn = xn.NextSibling; // <?xml version="1.0" ...> ignorieren

if (xn.NamespaceURI == schema) // entspricht gefundener Part dem gesuchten Schema?

{

return xDocCustomXML;

}

}

return null;

}

}

 

Wird dieses XMLDocument geändert, kann es so wieder zurück geschrieben werden:

private void WriteCustomXML(string FName, string schema, XmlDocument xDocNewCustomXML)

{

using (WordprocessingDocument wDoc = WordprocessingDocument.Open(FName, true))

{

MainDocumentPart mainPart = wDoc.MainDocumentPart;

foreach (CustomXmlPart custXML in mainPart.CustomXmlParts)

{

XmlDocument xDocCustomXML = new XmlDocument();

xDocCustomXML.Load(custXML.GetStream(FileMode.Open));

XmlNode xn = xDocCustomXML.FirstChild;

if (!xn.HasChildNodes) xn = xn.NextSibling; // <?xml version="1.0" ...> ignorieren

if (xn.NamespaceURI == schema) // entspricht gefundener Part dem gesuchten Schema?

{

using (StreamWriter sw = new StreamWriter(custXML.GetStream(FileMode.Open, FileAccess.Write)))

{

xDocNewCustomXML.Save(sw);

}

}

}

}

}

 

Da kann man nur hoffen, dass es bald eine weitere Iteration des Open XML SDK geben wird, die dann auch Objekte für Office Dokumente wie Zelle oder Paragraph bereitstellt.