Linq to XML
Dalla teoria alla pratica
Università di Genova
Facoltà di Ingegneria
Martedi 16 Dicembre 2008
Venerdi 19 Dicembre 2008
Email: [email protected]
Blog: http://blogs.ugidotnet.org/raffaele
Profilo: https://mvp.support.microsoft.com/profile/raffaele
IL PERCORSO VERSO I LINGUAGGI
FUNZIONALI
Extension Methods (C# 3.0)
• Sono metodi statici che possono essere invocati usando la
sintassi del metodo di istanza
• Vanno usati solo quando non è possibile fare diversamente
– WPF e Linq ne fanno largo uso per estendere classi già scritte
• Se nella classe estesa esiste già un metodo con quel
nome/parametri, ha la precedenza sull'extension method
namespace Raf.Helpers {
public static class StringHelper {
public static int ToInt32(this string s) {
return Int32.Parse(s);
}
}
}
using Raf.Helpers;
......
string s = "2007";
int i = s.ToInt32();
Anonymous methods (C# 2.0)
• C'erano una volta i delegate
button1.Click += new EventHandler(button1_Click);
...
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show((sender as Control).Name);
}
• Con C# 2.0 è possibile semplificare il loro uso:
button2.Click += delegate(object sender, EventArgs e)
{
MessageBox.Show("Click!");
};
• Semplificazione ...
C# 1.0
MyDlg del = new MyDlg(Method);
C# 2.0
MyDlg del = Method;
Espressioni Lambda (C# 3.0)
• Evoluzione naturale degli Anonymous Methods
– Offrono una sintassi concisa e funzionale per scrivere Anonymous
Methods
"goes to"
parametro in ingresso
x => x+1
elaborazione
• Sono tipiche dei linguaggi funzionali
• Rispetto agli Anonymous Methods
– I type delle espressioni Lambda possono non essere espliciti (saranno
dedotti)
– La Lambda può essere sia un'espressione che un blocco ({..})
– Le espressioni possono essere convertite in un albero di espressioni
• Le Lambda possono essere usate laddove è atteso un delegate
Timer t = new Timer(x => Console.WriteLine("Tic"), null, 0, 1000);
Lambda e i tipi "inferred" (dedotti)
double seconds = F
(
"1:15:30",
str => TimeSpan.Parse(str),
ts => ts.TotalSeconds);
static Z F<X, Y, Z>(
X value,
Func<X, Y> f1,
Func<Y, Z> f2) {
return f2(f1(value));
}
1.
"1:15:30" è assegnato a value.
–
2.
Il compilatore deduce che str sia string perché Parse accetta una string
TimeSpan.Parse(str) restituisce TimeSpan ed è associato a f1.
–
3.
Il tipo dedotto X è string
Il tipo dedotto di Y è System.TimeSpan
ts.TotalSeconds restituisce un double ed è associato a f2.
–
Il tipo dedotto Z è un double
Query Expressions (C# 3.0)
• Sintassi di query integrata nel linguaggio simile a SQL
– Validata dal compilatore e quindi strong-typed
• L'espressione di query inizia con la clausola "from" e termina
con una "select" o "group"
• Dopo "from" possono esserci un numero di clausole
– from  causa la generazione di una o più variabili di iterazione su una
sequenza o su una join di più sequenze
– let  causa il calcolo di un valore e introduce un identificatore che
rappresenta quel valore
– where  filtro che esclude dei valori dal risultato
– orderby  indica l'ordine del risultato
– select / group  determina la forma del risultato (tipo di oggetto)
– join  unisce due set di dati secondo un criterio
– into  permette di riusare il risultato in una nuova query
Expression Trees (C# 3.0)
• Rendono possibile vedere le Lambda come dati anziché
come codice eseguibile
• Un'espressione Lambda convertibile ad un tipo D è
convertibile ad un expression tree di tipo
System.Linq.Expression<D>
– È sufficiente che la lambda non abbia block statements
• In pratica sono un binary tree “dati” e non più codice
–
–
–
–
Serializzabile
Facilmente costruibile  designer!
Interpretabile
Permettono la conversione delle query nei provider Linq
Sintassi in azione
type inference
della variabile
locale
var contacts =
from c in customers
where c.State == "WA"
select new { c.Name, c.Phone };
Query
expressions
Lambda
expressions
var contacts =
customers
.Where(c => c.State == "WA")
.Select(c => new { c.Name, c.Phone });
Extension
methods
Anonymous
types
Object
initializers
LINQ To Objects
Restriction
Where
Projection
Select, SelectMany
Ordering
OrderBy, ThenBy
Grouping
GroupBy
Joins
Join, GroupJoin
Quantifiers
Any, All
Partitioning
Take, Skip, TakeWhile, SkipWhile
Sets
Distinct, Union, Intersect, Except
Elements
First, Last, Single, ElementAt
Aggregation
Count, Sum, Min, Max, Average
Conversion
ToArray, ToList, ToDictionary
Casting
OfType<T>, Cast<T>
Domande ?
LINQ TO XML
Perché una nuova API?
• XML DOM
– Molto completa ma anche complessa
– Gestione dei namespace non certo banale
• SAX
– Sequenziale e basato su eventi. Spesso inutilizzabile
• Stream (XmlReader / XmlWriter)
– Richiede apertura/chiusura di ogni tag. Molto prono ad errori
• XPath
– Abbastanza potente ma terribilmente difficile da debuggare
• Linq to XML
– Object oriented (es: supporto operatore +)
– Gerarchico (rispetta la natura di XML, più facile da leggere)
– Interrogabile con Linq (query potenti e semplici da esprimere)
XDocument
• Rappresenta il documento XML
• I metodi Load (statico) e Save permettono di leggere/scrivere
il documento da Stream, XmlReader/Writer, etc.
XDocument doc = XDocument.Load(@"c:\Temp\Rss.xml");
• Il metodo statico Parse permette di caricare da stringa
• Ha una proprietà Root che restituisce un XElement
• Ha una proprietà per dichiarare la declaration
– <?xml version="1.0" encoding="utf-8" standalone="yes"?>
XDocument doc = new XDocument();
doc.Declaration = new XDeclaration("1.0", "UTF-8", "yes");
• Ha una serie di metodi per aggiungere, eliminare, iterare gli
elementi e i suoi children
XNamespace
• Definisce un namespace XML
XNamespace ns = "http://www.unige.it";
• Supporta l'operatore + che restituisce un XName
XNamespace unige = "http://www.unige.it";
XElement root = new XElement(unige + "Root", "Hello, world");
<Root xmlns="http://www.unige.it">Hello, world</Root>
• XName è semplicemente una classe che combina il
namespace e il nome dell'elemento
– XName si può creare anche con la forma "{...}..."
XElement root = new XElement("{"http://www.unige.it"}Root", "Hello, world");
<Root xmlns="http://www.unige.it">Hello, world</Root>
Controllare i namespace
• Vogliamo avere controllo sul prefisso dei namespace
<unige:Root xmlns:unige="http://www.unige.it" xmlns:dist="http://dist.unige.it">
<dist:Child>
<unige:DifferentChild>other content</unige:DifferentChild>
</dist:Child>
<unige:Child2>c2 content</unige:Child2>
<dist:Child3>c3 content</dist:Child3>
</unige:Root>
XNamespace unige = "http://www.unige.it";
XNamespace dist = "http://dist.unige.it";
XElement root = new XElement(unige + "Root",
new XAttribute(XNamespace.Xmlns + "unige", unige),
new XAttribute(XNamespace.Xmlns + "dist", dist),
new XElement(dist + "Child",
new XElement(unige + "DifferentChild", "other content")
),
new XElement(unige + "Child2", "c2 content"),
new XElement(dist + "Child3", "c3 content")
);
XElement
• Un elemento semplice
XElement el = new XElement(ns + "Saluti", "Hello, world");
<Saluti xmlns=http://IAmRaf.net>Hello, world</Saluti>
• Composizione di elementi grazie a "params"
XElement el =
new XElement(ns + "Saluti",
new XAttribute("Language", "English"),
"Hello, world");
XElement root = new XElement(ns + "Parole",
new XElement(ns + "Saluti",
new XAttribute("Language", "English"),
"Hello, world"));
<Saluti Language="English" xmlns=http://IAmRaf.net>
Hello, world
</Saluti>
<Parole xmlns="http://IAmRaf.net">
<Saluti Language="English">Hello, world</Saluti>
</Parole>
I FORMATI E LE APPLICAZIONI
Il formato binario
(.doc, .xls, .ppt)
• Disponibili da sempre (sotto NDA)
• Oggi sono pubblici
• Convertibili in modo automatico e massivo
– Compatiblity pack e Migration Planning Manager sono free
• Usati solo per compatibilità verso i vecchi Office
– Nessun modo ufficiale per convertire verso il formato
binario
Iniziativa Open Protocols
• Pubblicati tutti i protocolli di comunicazione e i
formati usati da Windows e gli altri prodotti Microsoft
– http://msdn.microsoft.com/en-us/library/cc216514.aspx
– SMB, BITS, RDP, RPC/HTTP, ...
• SMB ... SaMBa per Linux ricorda qualcosa?
– Address Book format, Office Crypto ext., Sharepoint, SMTP
extensions (Exchange), ...
• Alcuni di questi sono soggetti a brevetti:
– http://www.microsoft.com/about/legal/intellectualproperty/protocols
Microsoft Office
•
Versione 97, 2000, XP
– Il file binario si può convertire in OOXML con i tool
– Il tool è disponibile anche in versione "Shell Extension"
•
Versione 2003
– Esiste un plugin che gestisce nativamente OOXML
•
Versione 2007
– Gestisce il formato ECMA di OOXML
•
Versione 2007 SP2 (primavera 2009)
– Gestisce anche ODF, PDF e XPS
nativamente
•
Versione "Office 14"
– Gestione del formato ISO di OOXML
Open Office
• Convertitori attuali
– La versione Novell già supporta OOXML
• La beta della versione 3.0 supporta OOXML
• Attualmente OpenOffice non supporta ODF
– http://www.griffinbrown.co.uk/blog/PermaLink.aspx?guid
=f0384bed-808b-49a8-8887-ea7cde5caace
OOXML per developers
• OOXML è un formato file standard ISO che definisce
la struttura di documenti di tipo Wordprocessing,
Spreadsheet, Presentation
– Office 2007 lo usa nativamente (docx, xlsx, pptx e derivati)
• OOXML è composto da due livelli di astrazione:
– Lo standard OPC
• Definisce il formato fisico (ZIP) e la gerarchia dei file contenuti
– Lo schema dei file XML che rappresentano il documento
IL PACKAGE OPC
Il Package OPC è un file ZIP
• Open Packaging Conventions (standard ISO)
– Il formato file è un normale ZIP
– La struttura interna è definita nello standard
Come manipolare un OPC
• Per leggere/scrivere un file OPC:
– Si può gestire "a mano" zip e xml
• Qualsiasi piattaforma può manipolare zip e xml
– Si possono usare le classi del Framework 3.0
• System.IO.Packaging.Package, etc.
– Si usa ad esempio per XPS
– Gestisce un 'generico' package
– Si può usare l'Office Open XML SDK
• DLL managed che include una serie di classi che conoscono le
"part" specifiche del package di OOXML
Leggere la 'part' principale
di un Package con OOXML SDK (1 e 2)
using (WordprocessingDocument doc = WordprocessingDocument.Open(_FileName, true))
{
MainDocumentPart mainPart = doc.MainDocumentPart;
Input
using (StreamReader streamReader = new StreamReader(mainPart.GetStream()))
{
using (XmlReader stream = XmlReader.Create(streamReader))
{
_MainDocument = XElement.Load(stream);
}
}
}
Output
XElement
using (SpreadsheetDocument xlPackage = SpreadsheetDocument.Open(_FileName, true))
{
WorkbookPart workbook = xlPackage.WorkbookPart;
OpenXmlPart part = workbook.GetPartById(Id);
using (StreamReader streamReader = new StreamReader(part.GetStream()))
{
using (XmlReader stream = XmlReader.Create(streamReader))
{
_CurrentSheet = XElement.Load(stream);
}
}
// ....
}
Word Processing Markup Language
WORDPROCESSINGML
WordprocessingML
• La "MainDocumentPart" contiene il corpo del documento
• Tramite relazioni OPC alla MainDocumentPart sono
collegati altri file XML
File binari per le immagini
HeaderPart: rappresenta gli header
FooterPart: rappresenta i footer
Settings part: le impostazioni per il viewer (Word), per la
compatibilità con versioni precedenti e la conversione in Html
– Numbering: le impostazioni sulla formattazione degli elenchi
putntati e numerati
– ... altre parts ...
–
–
–
–
Struttura e query di un documento
Informazioni essenziali
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document
xmlns:w=http://schemas.openxmlformats.org/wordprocessingml/2006/main
<w:body>
<w:p>
public IEnumerable<XElement> FindOccurrenceOf(string text)
<w:r>
{
<w:t>Hello, world</w:t>
var v =
</w:r>
from b in MainDocument.Descendants(NS_w + "body")
from p in b.Elements(NS_w + "p")
</w:p>
from r in p.Elements(NS_w + "r")
</w:body>
from t in r.Elements(NS_w + "t")
</w:document>
where ((string)t).Contains(text)
select t;
return v;
• Ogni tag appartiene ad un
namespace
}
xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
Formattazione
• Bold
<w:r>
<w:rPr>
<w:b/>
</w:rPr>
<w:t>Grassetto/w:t>
</w:r>
Italic
<w:r>
<w:rPr>
<w:i/>
</w:rPr>
<w:t>Corsivo</w:t>
</w:r>
Underline
<w:r>
<w:rPr>
<w:u/>
</w:rPr>
<w:t>Sottolinea</w:t>
</w:r>
public IEnumerable<string> GetBoldWords()
{
IEnumerable<string> words =
from b in MainDocument.Descendants(NS_w + "body")
from p in b.Elements(NS_w + "p")
from r in p.Elements(NS_w + "r")
where r.Descendants(NS_w + "rPr").Descendants(NS_w + "b").Count() == 1
select (string)r.Descendants(NS_w + "t").First();
return words;
}
Highlited
<w:r>
<w:rPr>
<w:highlight
w:val="yellow"/>
</w:rPr>
<w:t>Evidenziato</w:t>
</w:r>
Formattazione di run o paragrafo
•
Si possono formattare i paragrafi <pPr/> o i run <rPr/>
– Possono esistere più <r> dentro un paragrafo. Questo consente una formattazione
differenziata
•
Colore del testo (Test)
– <w:color w:val="FF0000"/>
•
StrikeThrough (Test)
– <w:strike/>
•
Superscript (Test)
– <w:vertAlign w:val="superscript"/>
•
Subscript (Test)
– <w:vertAlign w:val="subscript"/>
•
Font Size (Test)
– <w:sz w:val="40"/>
•
Dentro <t> si usa 'preserve' per conservare lo spazio a inizio o fine testo
– <w:t xml:space="preserve">: </w:t>
Formattazione di paragrafo
• Giustificazione
– <w:jc w:val="right"/> (left, center, both, ...)
• Spaziatura
– <w:spacing w:after="0" w:line="240" w:lineRule="auto"/>
– Conversioni
• Per i twips la conversione è (int)(val * 1440)
• La spaziatura si converte con (int)(NumLines * 240.0m)
• Le specifiche spiegano come, dove, quando
• Cambio pagina
– <w:r> ... <w:br w:type="page"/> ... </w:r>
Costuire un documento con
XDocument (Linq to XML)
• Creo con Word un documento
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:r>
<w:t>Simple Text</w:t>
</w:r>
</w:p>
</w:body>
</w:document>
• "Paste as XML"
XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XElement xml = new XElement(w + "document",
new XAttribute(XNamespace.Xmlns + "w", w),
new XElement(w + "body",
new XElement(w + "p",
new XElement(w + "r",
new XElement(w + "t", "Simple Text")
)
)
)
);
WORDPROCESSING DOCUMENT
SpreadSheet Markup Language
SPREADSHEETML
SpreadSheetML
•
Il file del WorkBook tiene solo l'elenco dei sheet
–
–
–
–
•
Un documento XML per ogni "Sheet"
In ogni Sheet c'è una root <sheetData />
Per ogni sheetData ci sono le <row/>
Per ogni row ci sono le <c /> (cells)
Cells:
– Attributo "r" definisce il reference espresso in stile "A1" (r="B2")
– Attributo "s" l'indice nella part degli stili (s="3")
– Attributo "t" definisce il data type
• b = bool, s = shared string, inlineStr = inline string, n = number
•
L'elemento child di <c> può essere
– Di solito <v> (value)
– Se t è inlineStr il child è <is>
• <c r="A1" t="inlineStr"> <is><t>inline string</t></is> </c>
– Se c'è una formula il child è <f />
• <c r="A2"> <f>A1+1</f> <v>2</v> </c>
• Il numero dentro <v /> è una cache ed è omissibile
Shared String Part
• Una lookup table definisce la lista delle shared string
• Dov'è la stringa?
– <c r="A3" s="1" t="s"> <v>0</v> </c>
• L'editor può fornire suggerimenti quando
si digitano le prime lettere di una
parola già presente nella tabella
• Le shared string sono in una part separata
• In alternativa si può usare inlineStr
– <c r="C1" t="inlineStr">
<is>
<t>inline string</t>
</is>
</c>
<v>0</v>
<v>1</v>
<sst xmlns="....." count="3"
uniqueCount="2">
<si>
<t>Rosso</t>
</si>
<si>
<t>Bianco</t>
</si>
</sst>
Caricare le shared string
private void LoadSharedStrings(WorkbookPart workbook)
{
if (_SharedStrings != null) return;
SharedStringTablePart Shared = workbook.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
if (Shared == null)
{
_SharedStrings = new List<SharedString>();
// lista vuota
return;
}
using (StreamReader streamReader = new StreamReader(Shared.GetStream()))
{
using (XmlReader stream = XmlReader.Create(streamReader))
{
int index = 0;
XElement shs = XElement.Load(stream);
_SharedStrings = from si in shs.Descendants(NS_ex + "si")
from t in si.Descendants(NS_ex + "t")
select new SharedString()
{
Text = t.Value,
Index = index++
};
}
}
}
Stili e formattazione
(relativi alla 'part' degli Styles)
• Dentro <styleSheet /> ci sono due livelli di formattazione
– <c r="B2" s="1"> <v>39451.413006267</v> </c>
Master style
Elemento 0
Stili referenziati dalle celle
Elemento 1
<cellStyleXfs count="1">
<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0">
<alignment horizontal="left" indent="0" textRotation="0" vertical="bottom" wrapText="0" />
</xf>
</cellStyleXfs>
<cellXfs count="2">
<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0">
<alignment horizontal="left" indent="0" textRotation="0" vertical="bottom" wrapText="0" />
</xf>
<xf numFmtId="14" fontId="0" fillId="0" borderId="1" xfId="0">
<alignment horizontal="left" indent="0" textRotation="0" vertical="bottom" wrapText="0" />
</xf>
<xf numFmtId="164" fontId="0" fillId="0" borderId="1" xfId="0">
<alignment horizontal="left" indent="0" textRotation="0" vertical="bottom" wrapText="0" />
</xf>
</cellXfs>
Stili e formattazione
• La data è solo un numero formattato in modo data
– fontId, fillId, etc. si riferiscono ai vari fragment xml
– numFmtId: la formattazione predefinita non necessita del
corrispondente <numFmt /> (vedi specs per la lista)
<numFmts count="1">
<numFmt numFmtId="164"
formatCode="#.##0,000000" />
</numFmts>
<fonts count="1">
<font>
<sz val="11" />
<color auto="1" />
<name val="Calibri" />
<family val="2" />
<scheme val="minor" />
</font>
</fonts>
<xf numFmtId="164" fontId="0" fillId="0" borderId="1" xfId="0">
<alignment horizontal="left" indent="0" textRotation="0" vertical="bottom" wrapText="0" />
</xf>
Cercare in uno SpreadSheetML
public IEnumerable<CellSearch> FindOccurrenceOf(string text)
{
var inlinesimple =
from d in _CurrentSheet.Descendants(NS_ex + "sheetData")
from row in d.Descendants(NS_ex + "row")
from c in row.Descendants(NS_ex + "c")
from istag in c.Descendants(NS_ex + "is")
from t in istag.Descendants(NS_ex + "t")
where t.Value.Contains(text)
select new CellSearch() { Cell = c.Attribute(XName.Get("r")).Value, Text = t.Value };
var inlinerich =
from d in _CurrentSheet.Descendants(NS_ex + "sheetData")
from row in d.Descendants(NS_ex + "row")
from c in row.Descendants(NS_ex + "c")
from istag in c.Descendants(NS_ex + "is")
from r in c.Descendants(NS_ex + "istag")
from t in istag.Descendants(NS_ex + "r")
where t.Value.Contains(text)
select new CellSearch() { Cell = c.Attribute(XName.Get("r")).Value, Text = t.Value };
var shared =
from d in _CurrentSheet.Descendants(NS_ex + "sheetData")
from row in d.Descendants(NS_ex + "row")
from c in row.Descendants(NS_ex + "c")
from v in c.Descendants(NS_ex + "v")
where c.Attribute(XName.Get("t")).Value == "s"
join ss in _SharedStrings on int.Parse(v.Value) equals ss.Index
where ss.Text.Contains(text)
select new CellSearch() { Cell = c.Attribute(XName.Get("r")).Value, Text = ss.Text };
var res = inlinesimple.Union(inlinerich).Union(shared);
return res;
}
LINK UTILI
Info di base
•
Home per developers
– http://openxmldeveloper.org/
•
Introduzione al formato OOXML
– http://msdn.microsoft.com/en-us/library/aa338205.aspx
•
Office OpenXML SDK 1.0
•
Documentazione
•
Download
–
–
•
http://msdn.microsoft.com/en-us/library/bb448854.aspx
http://www.microsoft.com/downloads/details.aspx?FamilyId=AD0B72FB-4A1D-4C52-BDB57DD7E816D046&displaylang=en
Office OpenXML SDK 2.0 CTP (no licenza go-live)
– Documentazione
•
http://msdn.microsoft.com/en-us/library/bb448854(office.14).aspx
– Download
•
•
http://www.microsoft.com/downloads/details.aspx?FamilyId=C6E744E5-36E9-45F5-8D8C331DF206E0D0&displaylang=en
Poster delle classi di OOXML
– http://www.microsoft.com/downloads/details.aspx?familyid=134BCB91-DD7B-4209-AC942699B9366874&displaylang=en
Documentazione standard OOXML
• Standard ECMA TC45 (Office 2007)
– http://www.ecmainternational.org/news/TC45_current_work/TC45_availabl
e_docs.htm
• Standard ISO/IEC 29500 (Office 14)
– http://standards.iso.org/ittf/PubliclyAvailableStandards/in
dex.html
Conversioni e migrazione
• Formato file binario
– http://www.microsoft.com/interop/docs/OfficeBinaryFormats.
mspx
• Office Compatibility Pack
– http://www.microsoft.com/downloads/details.aspx?FamilyID=9
41b3470-3ae9-4aee-8f43-c6bb74cd1466&displaylang=en
• Office Migration Planning Manager (OMPM)
– http://www.microsoft.com/downloads/details.aspx?FamilyID=1
3580cd7-a8bc-40ef-8281-dd2c325a5a81&DisplayLang=en
• Come eseguire conversioni automatiche e massive
– http://blogs.msdn.com/ericwhite/archive/2008/09/19/bulkconvert-doc-to-docx.aspx
Altri convertitori
•
Convertitore OOXML (WordprocessingML) in XAML (FlowDocument)
– http://www.codeplex.com/Word2007ToXaml
•
Convertitore doc to docx (presto anche gli altri)
– http://b2xtranslator.sourceforge.net/
– Creato da DIaLOGIKa con Microsoft
•
Daisy: Digital Accessible Information System
– http://sourceforge.net/projects/openxml-daisy
– Altre news:
• http://blogs.technet.com/reedblog/archive/2008/01/25/open-xml-to-daisy-v1-is-live.aspx
•
OOXML <-> ODF
– http://odf-converter.sourceforge.net/
•
Open Office (ODF)
– Sun Plugin
• http://www.sun.com/software/star/odf_plugin/index.jsp
– Novell lo include nativamente
Tools per OOXML
• PowerTools (per PowerShell)
– Iniziativa su Codeplex per script di PowerShell
• http://www.codeplex.com/PowerTools
• http://blogs.msdn.com/ericwhite/pages/PowerTools.aspx
– Requisiti: Visual Studio express, PowerShell, OpenXML SDK
• Altova Tool per OOXML
– http://www.altova.com/
dev_portal_ooxml.html
• XML "Paste As Linq"
– Esempi VS2008 (CSharpSamples.zip)
• LinqSamples\PasteXmlAsLinq
• Word 2007 Content Control Toolkit (customXml e binding)
– http://www.codeplex.com/dbe
Bloggers
• http://blogs.msdn.com/dmahugh
• http://blogs.msdn.com/ericwhite
• http://blogs.msdn.com/brian_jones
Domande ?
Adozione dei formati
• Google trends
– http://www.google.com/trends?q=.docx%2C+.odt
– http://www.google.com/trends?q=.xlsx%2C+.ods
I Power Tools per OOXML
Accept-OpenXmlChange
Add-OpenXmlContent
Add-OpenXmlDigitalSignature
Add-OpenXmlDocumentIndex
Add-OpenXmlDocumentTOA
Add-OpenXmlDocumentTOC
Add-OpenXmlDocumentTOF
Add-OpenXmlPicture
Export-OpenXmlSpreadsheet
Export-OpenXmlToHtml
Export-OpenXmlWordprocessing
Get-OpenXmlBackground
Get-OpenXmlComment
Get-OpenXmlCustomXmlData
Get-OpenXmlDigitalSignature
Get-OpenXmlDocument
Get-OpenXmlFooter
Get-OpenXmlHeader
Get-OpenXmlStyle
Get-OpenXmlTheme
Get-OpenXmlWatermark
Lock-OpenXmlDocument
Remove-OpenXmlComment
Remove-OpenXmlDigitalSignature
Set-OpenXmlBackground
Set-OpenXmlContentFormat
Set-OpenXmlContentStyle
Set-OpenXmlCustomXmlData
Set-OpenXmlFooter
Set-OpenXmlHeader
Set-OpenXmlStyle
Set-OpenXmlTheme
Set-OpenXmlWatermark
Scarica

Linq to XML Dalla teoria alla pratica