Artykuły

A A A
Drukuj Ekportuj do PDF
Opublikowane: 2009.10.25 18:50 | Maciej Zbrzezny | Aktualizacja: 2010.01.21 2:04

Wprowadzenie do Open XML Format SDK 2.0

tagi: XML
Microsoft w tym (2009) roku opublikował kolejną wersję pakietu SDK do manipulacji dokumentów w formacie OpenXML. Pakiet ten ma za zadanie ułatwić tworzenie i edycję plików w formacie OpenXML z poziomu języka programowania (np. C#), automatyzując standardowe operacje jakie zwykle implementować muszą programiści tworzący aplikacje wykorzystujące ten format. W tym artykule chciałbym przedstawić sposoby wykorzystania tego pakietu. Oraz przybliżyć czytelnikom jak można wykreować dokument typu DOCX z

Microsoft w tym roku opublikował kolejną wersję pakietu SDK do manipulacji dokumentów w formacie OpenXML. Pakiet ten ma za zadanie ułatwić tworzenie i edycję plików w formacie OpenXML z poziomu języka programowania (np. C#), automatyzując standardowe operacje jakie zwykle implementować muszą programiści tworzący aplikacje wykorzystujące ten format. Pakiet można pobrać ze stron Microsoft'u: http://www.microsoft.com/downloads/details.aspx?FamilyID=C6E744E5-36E9-45F5-8D8C-331DF206E0D0&displaylang=en.

Więcej informacji na temat pakietu i formatu Open XML można znaleźć tutaj:

W tym artykule chciałbym się skupić na pokazaniu kilku przykładów z wykorzystania tego pakietu.

Pierwszy program ("Hello Word" w OpenXML)

Aby stworzyć dowolną aplikację wykorzystującą Open Xml Format SDK, do projektu należy dodać następujące referencje:

  • DocumentFormat.OpenXml
  • WindowsBase

W kodzie dołączamy następujące przestrzenie nazw:

  • DocumentFormat.OpenXml;
  • DocumentFormat.OpenXml.Packaging;
  • DocumentFormat.OpenXml.Wordprocessing;

Teraz zobaczmy funkcję realizującą proste "Hello World" w OpenXML:

[Kod C#]
private void HelloWorld(string documentFileName)
{
// Create a Wordprocessing document.
using (WordprocessingDocument myDoc = WordprocessingDocument.Create(documentFileName, WordprocessingDocumentType.Document))
{
// Add a new main document part.
MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
//Create Document tree for simple document.
mainPart.Document = new Document();
//Create Body (this element contains other elements that we want to include
Body body = new Body();
//Create paragraph
Paragraph paragraph = new Paragraph();
Run run_paragraph = new Run();
// we want to put that text into the output document
Text text_paragraph = new Text("Hello World!");
//Append elements appropriately.
run_paragraph.Append(text_paragraph);
paragraph.Append(run_paragraph);
body.Append(paragraph);
mainPart.Document.Append(body);
// Save changes to the main document part.
mainPart.Document.Save();
}
}


Powyższa funkcja tworzy dokument w pliku podanym przez użytkownika. Do dokumentu dodany jest paragraf który zawiera tekst "Hello World!". W ostatnim kroku dokument jest zapisywany.

Warto również przyjrzeć się zawartości generowanej przez tą funkcję i zapisanej w języku WordprocessingML:

				
[Kod XML]
<?xml version="1.0" encoding="utf-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:r>
<w:t>Hello World!</w:t>
</w:r>
</w:p>
</w:body>
</w:document>

Jak widać w powyższym kodzie XML widać duże powiązanie pomiędzy kodem napisanym w C#, a powyższym. Zadeklarowany jest dokument (document = WordprocessingDocument) wewnąrz którego jest część Body (body), w niej znajduje się paragraf (p = Paragraph) z elementem typu Run (r) i odpowiednim tekstem (t = Text).

A jak tą funkcję wykorzystać? Poniższy przykład pyta użytkownika o plik, do którego ma być zapisany tekst, wywołuje wcześniej stworzoną funkcję i otwiera przygotowany plik przy pomocy Word (lub innej ustawionej w systemie przeglądarki plików docx).

				
[Kod C#]
SaveFileDialog mySaveFileDialog=new SaveFileDialog();
mySaveFileDialog.Filter = "Word 2007 file (DOCX)|*.docx";
//save dialog display:
if (mySaveFileDialog.ShowDialog() == DialogResult.OK)
{
//call creation of HellowWord document
HelloWorld(mySaveFileDialog.FileName);
// let's open this document in Word:
Process.Start(mySaveFileDialog.FileName);
}

Style

Teraz można iść nieco dalej i dołożyć elementy związane z formatowaniem tekstu, czyli zajmę się teraz stylami.Załóżmy, że chcemy przygotować dokument, który będzie się składał z dwóch linijek tekstu. Pierwsza linijka będzie nagłówkiem akapitu, druga tekstem akapitu. To jak przygotować zwykły tekst (tak jak tutaj w drugiej linijce) pisałem o tym już wcześniej, tym razem napiszę jak przygotować tą pierwszą (odpowiednio sformatowaną) linijkę.

Pierwszą czynnością jaką należy wykonać, to trzeba dodać do tworzonego dokumentu część związaną z definicją stylów (dodajemy ją do głównego elementu dokumentu):

				
[Kod C#]
WordprocessingDocument myDoc = WordprocessingDocument.Create(documentFileName, WordprocessingDocumentType.Document)
MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
StyleDefinitionsPart stylePart = mainPart.AddNewPart<StyleDefinitionsPart>();

Definiujemy teraz czcionkę (Font), którą chcemy wykorzystać (w tym przykładzie: czerwony i pogrubiony Arial, rozmiaru 28):

				
[Kod C#]
// we have to set the properties
RunProperties rPr = new RunProperties();
Color color = new Color() { Val = "FF0000" }; // the color is red
RunFonts rFont = new RunFonts();
rFont.Ascii = "Arial"; // the font is Arial
rPr.Append(color);
rPr.Append(rFont);
rPr.Append(new Bold()); // it is Bold
rPr.Append(new FontSize() { Val = 28 }); //font size (in 1/72 of an inch)

Teraz czas na definicję stylu, będzie się on nazywać "My Heading 1", a jego identyfikator (używany później w dokumencie) to "MyHeading1". Oto definicja:

				
[Kod C#]
//creation of a style
Style style = new Style();
style.StyleId = "MyHeading1"; //this is the ID of the style
style.Append(new Name() { Val = "My Heading 1" }); //this is name
style.Append(new BasedOn() { Val = "Heading1" }); // our style based on Normal style
style.Append(new NextParagraphStyle() { Val = "Normal" }); // the next paragraph is Normal type
style.Append(rPr);//we are adding properties previously defined

W tym momencie nadszedł czas na dodanie stworzonego stylu do dokumentu i zapisanie części związanej ze stylami:

				
[Kod C#]
// we have to add style that we have created to the StylePart
stylePart.Styles = new Styles();
stylePart.Styles.Append(style);
stylePart.Styles.Save(); // we save the style part

Styl mamy już stworzony, teraz trzeba go przypisać do jakiegoś paragrafu. Słyży do tego klasa ParagraphProperties, której trzeba przypisać odpowiednie ParagraphStyleId. Przykład poniżej:

				
[Kod C#]
Paragraph heading = new Paragraph();
Run heading_run = new Run();
Text heading_text = new Text("This is Heading");
ParagraphProperties heading_pPr = new ParagraphProperties();
heading_pPr.ParagraphStyleId = new ParagraphStyleId() { Val = "MyHeading1" }; // we set the style
heading.Append(heading_pPr);
heading_run.Append(heading_text);
heading.Append(heading_run);

Teraz można już cieszyć się efektem naszych prac (przykład jest na załączonym rysunku), zobaczmy jeszcze całą procedurę która generuje ten dokument:

				
[Kod C#]
private void HelloWorld_withStyle(string documentFileName)
{
// Create a Wordprocessing document.
using (WordprocessingDocument myDoc = WordprocessingDocument.Create(documentFileName, WordprocessingDocumentType.Document))
{
// Add a new main document part.
MainDocumentPart mainPart = myDoc.AddMainDocumentPart();

//Add new style part
StyleDefinitionsPart stylePart = mainPart.AddNewPart();
// we have to set the properties
RunProperties rPr = new RunProperties();
Color color = new Color() { Val = "FF0000" }; // the color is red
RunFonts rFont = new RunFonts();
rFont.Ascii = "Arial"; // the font is Arial
rPr.Append(color);
rPr.Append(rFont);
rPr.Append(new Bold()); // it is Bold
rPr.Append(new FontSize() { Val = 28 }); //font size (in 1/72 of an inch)
//creation of a style
Style style = new Style();
style.StyleId = "MyHeading1"; //this is the ID of the style
style.Append(new Name() { Val = "My Heading 1" }); //this is name
style.Append(new BasedOn() { Val = "Heading1" }); // our style based on Normal style
style.Append(new NextParagraphStyle() { Val = "Normal" }); // the next paragraph is Normal type
style.Append(rPr);//we are adding properties previously defined
// we have to add style that we have created to the StylePart
stylePart.Styles = new Styles();
stylePart.Styles.Append(style);
stylePart.Styles.Save(); // we save the style part

//Create Document tree for simple document.
mainPart.Document = new Document();
//Create Body (this element contains other elements that we want to include
Body body = new Body();
//Create paragraph
Paragraph paragraph = new Paragraph();
Run run_paragraph = new Run();
// we want to put that text into the output document
Text text_paragraph = new Text("Hello World!");
//Append elements appropriately.
run_paragraph.Append(text_paragraph);
paragraph.Append(run_paragraph);
Paragraph heading = new Paragraph();
Run heading_run = new Run();
Text heading_text = new Text("This is Heading");
ParagraphProperties heading_pPr = new ParagraphProperties();
heading_pPr.ParagraphStyleId = new ParagraphStyleId() { Val = "MyHeading1" }; // we set the style
heading.Append(heading_pPr);
heading_run.Append(heading_text);
heading.Append(heading_run);
body.Append(heading);
body.Append(paragraph);
mainPart.Document.Append(body);
// Save changes to the main document part.
mainPart.Document.Save();
}
}

A co z kodem zapisanym przy pomocy WordprocessingML? W tym przypadku generowane są dwa pliki, jeden zawierający definicję stylu:

				
[Kod XML]
<?xml version="1.0" encoding="utf-8"?>
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:style w:styleId="MyHeading1">
<w:name w:val="My Heading 1" />
<w:basedOn w:val="Heading1" />
<w:next w:val="Normal" />
<w:rPr>
<w:color w:val="FF0000" />
<w:rFonts w:ascii="Arial" />
<w:b />
<w:sz w:val="28" />
</w:rPr>
</w:style>
</w:styles>

oraz drugi z definicją z konkretnym dokumentem:

[Kod XML]
<?xml version="1.0" encoding="utf-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="MyHeading1" />
</w:pPr>
<w:r>
<w:t>This is Heading</w:t>
</w:r>
</w:p>
</w:body>
</w:document>

Jak widać w tym przypadku otrzymujemy kod WordProcessingML bardzo podobny do tego z poprzedniego przykładu, jednak  dodana została specjalna właściwość (pPr = ParagraphProperties), w której został wybrany odpowiedni styl (pStyle = ParagraphStyleId), który jest zdefiniowany w innym pliku.

Wyrównanie tekstu

Zajmijmy się teraz wyrównaniem tekstu: do lewej, do prawej, do środka i wyjustowaniem tekstu. Jak można ustawiać wyrównanie tekstu? W tym celu należy ustawić odpowiednie właściwości paragrafu dla stylu, który chcemy zmienić lub paragrafu w którym chcemy ustawić wyrównanie. Wykorzystujemy więc właściwość Justification klasy ParagraphProperties, której należy nadać wartość wchodzącą w skład elementu wyliczeniowego: JustificationValues Enumeration, o następujących elementach:
  • Center: Center (Equation)
  • CenterGroup: Centered as Group (Equations)
  • Left: Left Justification
  • Right: Right

Zakończmy więc teorię i przejdźmy do kodu, który będzie krótki i łatwy. Zakładając że na przykład chcemy wycentrować dany tekst (w paragrafie, bądź przy użyciu stylu) wystarczy wykonać następujący kod:

[Kod C#]
paragraph_or_style.Append( new ParagraphProperties(
new Justification() { Val = JustificationValues.Center } ) );

Kod ten powoduje dodanie do dokumentu, napisanego w WordProcessingML, następującego kodu XML:

[Kod XML]
<w:jc w:val="center"/>

Tutaj ważna jest jeszcze jedna kwestia, a mianowicie odpowiednie formatowanie powinno być dodane do elementu paragrafu na początku i koniecznie przed dodaniem do niego tekstu, czyli np. oczekiwany efekt uzyskamy wykonując kod:

[Kod C#]
 Paragraph paragraph = new Paragraph();
Run run_paragraph = new Run();
// we want to put that text into the output document
Text text_paragraph = new Text( "Hello World!" );
//Append elements appropriately.
run_paragraph.Append( text_paragraph );
paragraph.Append( new ParagraphProperties(
new Justification() { Val = JustificationValues.Center } ) );
paragraph.Append( run_paragraph );

Natomiast tekst nie zostanie sformatowany, gdy do paragrafu najpierw został by dodany element Run, a dopiero później ParagraphProperties.

Tabele

 Zajmijmy się teraz tworzeniem tabel przy pomocy Open XML Format SDK. Dzięki wygodnemu API jakie oferuje Open XML Format SDK tworzenie tabel jest bardzo proste i polega na dodaniu do głównego dokumentu elementu typu Table, w którym następnie osadzamy elementy typu TableRow i TableCell. Najprostszy przykład takiej tabeli wygląda następująco:

[Kod C#]
Body body = new Body();
Table table = new Table(new TableRow(new TableCell(
new Paragraph(new Run(new Text("Hello World!"))))));
body.Append(table);

Teraz w najbliższym przykładzie stworzymy tabelkę z tabliczką mnożenia (zupełnie taką jak w szkole ;) ):

Multiplication table

*

1

2

3

4

5

6

7

8

9

10

1

1

2

3

4

5

6

7

8

9

10

2

2

4

6

8

10

12

14

16

18

20

3

3

6

9

12

15

18

21

24

27

30

4

4

8

12

16

20

24

28

32

36

40

5

5

10

15

20

25

30

35

40

45

50

6

6

12

18

24

30

36

42

48

54

60

7

7

14

21

28

35

42

49

56

63

70

8

8

16

24

32

40

48

56

64

72

80

9

9

18

27

36

45

54

63

72

81

90

10

10

20

30

40

50

60

70

80

90

100

Na początku pokazałem jak przygotować prostą tabelkę, poprzez osadzanie elementów komórki i wiersza w tabeli. Teraz, w przykładzie też będziemy osadzać w sobie obiekty TableRow i TableCell, ale dodatkowo zadbamy jeszcze o krawędzie i ustawimy by komórka w pierwszym wierszu tabeli rozszerzona była na wszystkie kolumny poniżej.

Zacznijmy więc do ustawienia obramowania, dla całej tabeli ustawimy proste pojedyncze obramowanie, w tym celu wykorzystujemy klasy: TableProperties i TableBorders. Przykład poniżej:

[Kod C#]
Table table = new Table();
TableProperties tblPr = new TableProperties();
TableBorders tblBorders = new TableBorders();
tblBorders.TopBorder = new TopBorder();
tblBorders.TopBorder.Val = new EnumValue<BorderValues>(BorderValues.Single);
tblBorders.BottomBorder = new BottomBorder();
tblBorders.BottomBorder.Val =new EnumValue<BorderValues>( BorderValues.Single);
tblBorders.LeftBorder = new LeftBorder();
tblBorders.LeftBorder.Val = new EnumValue<BorderValues>(BorderValues.Single);
tblBorders.RightBorder = new RightBorder();
tblBorders.RightBorder.Val = new EnumValue<BorderValues>(BorderValues.Single);
tblBorders.InsideHorizontalBorder = new InsideHorizontalBorder();
tblBorders.InsideHorizontalBorder.Val = BorderValues.Single;
tblBorders.InsideVerticalBorder = new InsideVerticalBorder();
tblBorders.InsideVerticalBorder.Val = BorderValues.Single;
tblPr.Append(tblBorders);
table.Append(tblPr);

Zajmijmy się teraz pierwszym wierszem i jego komórką, dla której musimy ustawić cechę by była rozszerzona na 11 kolumn znajdujących się niżej. W tym celu ustawiamy odpowiednie właściwości komórki (TableCellProperties), a dokładniej właściwość GridSpan.

[Kod C#]
tr = new TableRow();
tc = new TableCell(new Paragraph(new Run(new Text("Multiplication table"))));
TableCellProperties tcp=new TableCellProperties();
GridSpan gridSpan=new GridSpan();
gridSpan.Val=11;
tcp.Append(gridSpan);
tc.Append(tcp);
tr.Append(tc);

Teraz zostają już do wykonania tylko proste wyliczenia i ostatecznie otrzymujemy funkcję

[Kod C#]
public void HelloWorld_table(string docName)
{
// Create a Wordprocessing document.
using (WordprocessingDocument myDoc = WordprocessingDocument.Create(docName, WordprocessingDocumentType.Document))
{
// Add a new main document part.
MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
//Create DOM tree for simple document.
mainPart.Document = new Document();
Body body = new Body();
Table table = new Table();
TableProperties tblPr = new TableProperties();
TableBorders tblBorders = new TableBorders();
tblBorders.TopBorder = new TopBorder();
tblBorders.TopBorder.Val = new EnumValue
(BorderValues.Single);
tblBorders.BottomBorder = new BottomBorder();
tblBorders.BottomBorder.Val =new EnumValue( BorderValues.Single);
tblBorders.LeftBorder = new LeftBorder();
tblBorders.LeftBorder.Val = new EnumValue(BorderValues.Single);
tblBorders.RightBorder = new RightBorder();
tblBorders.RightBorder.Val = new EnumValue(BorderValues.Single);
tblBorders.InsideHorizontalBorder = new InsideHorizontalBorder();
tblBorders.InsideHorizontalBorder.Val = BorderValues.Single;
tblBorders.InsideVerticalBorder = new InsideVerticalBorder();
tblBorders.InsideVerticalBorder.Val = BorderValues.Single;
tblPr.Append(tblBorders);
table.Append(tblPr);
TableRow tr;
TableCell tc;
//first row - title
tr = new TableRow();
tc = new TableCell(new Paragraph(new Run(new Text("Multiplication table"))));
TableCellProperties tcp=new TableCellProperties();
GridSpan gridSpan=new GridSpan();
gridSpan.Val=11;
tcp.Append(gridSpan);
tc.Append(tcp);
tr.Append(tc);
table.Append(tr);
//second row
tr = new TableRow();
tc = new TableCell();
tc.Append(new Paragraph(new Run(new Text("*"))));
tr.Append(tc);
for (int i = 1; i <= 10; i++)
{
tr.Append(new TableCell(new Paragraph(new Run(new Text(i.ToString())))));
}
table.Append(tr);
for (int i = 1; i <= 10; i++)
{
tr = new TableRow();
tr.Append(new TableCell(new Paragraph(new Run(new Text(i.ToString())))));
for (int j = 1; j <= 10; j++)
{
tr.Append(new TableCell(new Paragraph(new Run(new Text((i*j).ToString())))));
}
table.Append(tr);
}
//appending table to body
body.Append(table);
// and body to the document
mainPart.Document.Append(body);
// Save changes to the main document part.
mainPart.Document.Save();
}
}

W wyniku działania tej funkcji zostanie wygenerowana następująca zawartość zapisana w języku WrodprocessingML:

[Kod XML]
<?xml version="1.0" encoding="utf-8" ?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:tbl>
<w:tblpr>
<w:tblborders>
<w:top w:val="single" />
<w:left w:val="single" />
<w:bottom w:val="single" />
<w:right w:val="single" />
<w:insideh w:val="single" />
<w:insidev w:val="single" />
</w:tblborders>
</w:tblpr>
<w:tr>
<w:tc>
<w:p>
<w:r>
<w:t>Multiplication table</w:t>
</w:r>
</w:p>
<w:tcpr>
<w:gridspan w:val="11" />
</w:tcpr>
</w:tc>
</w:tr>
<w:tr>
<w:tc>
<w:p>
<w:r>
<w:t>*</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:p>
<w:r>
<w:t>1</w:t>
</w:r>
</w:p>
</w:tc>
<!—- many cells and rows declarations -->
</w:tr>
</w:tbl>
</w:body>
</w:document>

Czyli mamy tutaj takie elementy jak tabela (tbl = Table ) z odpowiednimi właściwościami (tblpr = TableProperties ) i ramkami (tblborders = TableBorders ), w której znajdują się wiersze (tr = TableRow ) i kolumny (tc = TableCell ).

Jak widać na powyższych przykłach jest duży związek pomiędzy wykorzystywanymi elementami pakietu Open Document Format SDK a konkretnym elementami zapisywanymi w języku WordProcessingML, dlatego jeżli nie wiemy jak coś przygotować przy pomocy SDK, można zawsze przygotować odpowiedni plik przy pomocy edytora tekstu (np. Word), a następnie sprawdzić, co rzeczywiście zostało w nim utworzone (w następnej sekcji opowiem jak to zrobić).

Zajrzyjmy w głąb formatu "docx"

Na koniec przeanalizujmy jak zbudowane są pliki oparte o format Open XML? Każdy z nich jest zestawem plików (głównie XML), które następnie są spakowane przy pomocy standardowego algorytmu zip, co w efekcie daje plik wynikowy. Dlatego można dowolnemu plikowi opartemu o ten format zmienić rozszerzenie (lub dodać kolejne) na zip, a następnie rozpakować zawartość tak spreparowanego archiwum. Tak na marginesie dodam, że w przypadku formatu rywala, czyli ODF (Open Document Format) idea pakowania algorytmem zip jest dokładnie taka sama.

Zobaczmy na przykład pliku Test.docx, któremu dodałem rozszerzenie zip i w efekcie otrzymałem plik Test.docx.zip, którego zawartość przedstawiona jest poniżej:

Test.docx.zip
| [Content_Types].xml
|
+---docProps
| app.xml
| core.xml
|
+---word
| | document.xml
| | fontTable.xml
| | numbering.xml
| | settings.xml
| | styles.xml
| | webSettings.xml
| |
| +---media
| | image1.gif
| | image2.gif
| | image3.gif
| | image4.gif
| | image5.gif
| | image6.gif
| |
| +---theme
| | theme1.xml
| |
| \---_rels
| document.xml.rels
|
\---_rels
.rels

Najbardziej oczywiście interesującym nas plikiem zwykle jest plik: word\document.xml, który zawieraa właściwy dokument. Plik ten w przypadku formatu Word 2007 (docx) jest zgodny z językiem WordProcessingML. Właśnie tam możemy znaleźć informacje na temat układu elementów XML, które w efekcie dają efekt, jaki widzimy podczas edycji tego dokumentu w edytorze Word.

Reasumując gdy nie wiemy jakich elementów użyć (i jak je poukładać) by uzyskać dokument Word o zadanej strukturze, można tą strukturę stworzyć przy pomocy edytora Word , a następnie "rozpakować" plik i podejrzeć jak to jest zrobione, Być może dla niektórych czytelników to banał, ale przyznam, że sam z tej metody korzystam. Jest ona prosta i skuteczna.

Podsumowanie

Mam nadzieję że w tym artykule przybliżyłem czytelnikom sposoby tworzenia dokumentów typu DOCX (zgodnych z formatem Open XML). Oczywiście zaprezentowane tutaj przykłady pokazują zaledwie skrawek wszystkich możliwości pakietu i formatu OpenXML.

Zachęcam do odwiedzenia mojego bloga: http://maciej-progtech.blogspot.com - znajdują tam się inne interesujące artykuły i materiały.

Historia

  • 2009.04.27 - 2009.08.11 - Pierwsza wersja artykułu opublikowana w częściach na moim blogu.
  • 2009.10.25 - Kolejna wersja artykułu przygotowana na portal CodeGuru.pl

Załączniki:


Podobne artykuły

28 czerwca 2007 Podpisy XML w .NET

Komentarze 12 Masz uwagi do tej strony? Napisz

User 83812 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 

Witam

Bardzo ciekawy artykuł moblizujący do dalszych poszukiwań, a także coś nowego na CG a nie następny artykuł z cyklu 'jak zaimplementować ...'.

Podobało się: Postawiony cel, przedstawienie różnych punktów widzenia, przyjemny do czytania język, oraz wyciągniete wnioski na końcu artykułu.

Brakowało: Jakieś małego przykładu na jakim można byłoby porównać różne podejścia do rozwiązania tego samego problemu (może propozycja jakiś metryk?). Wiem, że temat jest rozgległy, ale może warto byłyby wspomnieć też o sposobie podejścia do rozwiązywania problemów (Top-Down, Bottom-Up). Spróbować pokazać jak on wpływa na projektowanie systemu.

Ogólnie bardzo dobry artykuł, który mam nadzieje, wzbudzi większą dyskuję wśród społeczności. Czekam na kontynuację.

Ocena: 6.

Pozdrawiam
Łukasz

kazikkuta 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar VIP
 
Naprawdę bardzo dobry artykuł na ten temat.


Wiadomo, że największym marzeniem Człowieka jest latać i nie spaść na ryj.
 
potem

widget 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Polecam: "Projektowanie zorientowane obiektowo. Wzorce projektowe." Alan Shalloway, James R. Trott Artykuł świetnie służy jako wstęp do książki :)
User 114134 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Świetny artykul, gratuluje. Ode mnie 7. Dawno juz nie bylo na CG czekos ciekawego do poczytania, a tu prosze, taka perełka ;)
User 79013 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Grratuluję świetnego tesktu... i czekam na więcej ;-)

   ,,,^..^,,,
pozdrawiam
      stic

n-j 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Artykuł wg. mnie implementuje interfejsy:
IReadable, lekko się czytało, zostało poczucie bobrze spędzonego czasu
ICreative - jest niesztampowy
IUnique, bo jest jak żaden inny, które przeczytałem do tej pory*  *=nie czytałem źródeł...
INew, bo przynosi powiew świeżości. Nie w implementacji - nie tworzy nowego elementu w istniającej klasie/tabeli wzorców projektowych, czy implementacji danego wzorca. On tworzy nową klasę.
IMotivating - wiadomo.

Gratuluję i dziękuję.

Andrzej

__try_cast(Managed C++ 2003)@.net 1.1&VS 2003 sp1; NET Reflector , NUnit  - podlej kwiaty
User 94244 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Gdyby ktoś chciał poczytać więcej w tym kontekście to polecam:
http://helion.pl/ksiazki/refawp.htm.
dartar 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Potwierdzam. Bardzo dobry artykuł, ze "świeżym" podejsciem do tematu.
---
Pozdrawiam
http://DariuszTarczynski.blogspot.com
User 85718 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Artykuł ciekawy, jednak nie nazwał bym go rewolucyjnym(chyba że chodzi o rewolucyjność na portalu :) ), stwierdza on raczej pewne już ugruntowane fakty na temat samych wzorców oraz przyczyn ich powstania.
Jak najbardziej się zgadzam z podejściem autora że wzorców nie trzeba i nie wolno uczyć się na pamięć, wynikają one właśnie z tych wymienionych reguł projektowania obiektowego i tak na dobrą sprawę jeżeli ktoś tych reguł nie zna i nie rozumie to i nie zastosuje odpowiednio wzorców, i w drugą stronę jeżeli ktoś rozumie i zna te reguły to automatycznie będzie tworzył rozwiązania elastyczne.


User 93906 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Moja wiedza na temat wzorców projektowych wzieła się kilka lat temu właśnie z książki autorstwa Shalloway'a i Trott'a. Dzięki temu czytając ten artykuł mogłem w bardzo ciekawy, a co najważniejsze zwięzły i kontkretny sposób odświeżyć sobie te idee, o których się często zapomina. Polecam go także dla tych, którzy dopiero zaczynają się interesować wzorcami.

Jeśli chodzi zaś o formę to popieram to, że nie jest to kolejny długaśny artykuł z tonami kodu źródłowego w stylu "jak zaimplementować...", które zalegają mój folder ToRead w bookmarkach.

+6



User 94760 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 

klasa to nie zbior obiektow. Zbiorem obiektow jest ekstensja. Jedna z definicji klasy:

Klasa jest miejscem przechowywania tych informacji dotyczących obiektów, które są dla nich niezmienne, wspólne lub dotyczą całej ich populacji.   
 

olo1234 2010.01.21 1:10
0 oceń pozytywnie   oceń negatywnie 0
avatar
 
Artykuł jest OK. Fajnie się czyta.

Dodaj komentarz

avatar

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.

Autor Maciej Zbrzezny
avatar
 

Nazywam się Maciej Zbrzezny, jestem programistą, który interesuje się i zajmuje również architekturą oprogramowania. Tworzę oprogramowanie wykorzystujące platformę .NET(głównie C#) i OPC.

Załóż konto
CodeGuru to miejsce dla każdego programisty. Przez lata portal rozwijany był siłami społeczności i to właśnie społeczność programistów jest tutaj najważniejsza. CG od wielu lat gromadzi wokół siebie coraz większą grupę pasjonatów. Warto być jej częścią!

Dowiedz się więcej o CodeGuru