Created
March 16, 2017 16:35
-
-
Save Gelio/cb534b6612dd011f125a365230e90559 to your computer and use it in GitHub Desktop.
Object oriented design XML cheatsheet (with snippets of C# to handle typical serialization behavior)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" | |
xmlns:bk="http://bookstore.mini.pw.edu.pl/" | |
> | |
<xsl:output method="html" indent="yes"/> | |
<xsl:template match="/bk:Bookstore"> | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
<title>Bookstore</title> | |
<style type="text/css"> | |
<![CDATA[ | |
table,td,th { | |
border: 1px solid black; | |
} | |
table { | |
margin-top: 1em; | |
} | |
.it { | |
background-color: #AAA; | |
} | |
.math { | |
background-color: #CCC; | |
} | |
]]> | |
</style> | |
</head> | |
<body> | |
<xsl:call-template name="publications" /> | |
<xsl:call-template name="items" /> | |
</body> | |
</html> | |
</xsl:template> | |
<xsl:template name="publications"> | |
<table> | |
<tr> | |
<th>Author</th> | |
<th>Title</th> | |
<th>Type</th> | |
<th>Co-authors</th> | |
</tr> | |
<xsl:for-each select="bk:People/bk:Person"> | |
<xsl:sort select="bk:Surname"/> | |
<xsl:variable name="person" select="current()" /> | |
<xsl:for-each select="//bk:AuthorReference[@ref=$person/@id]"> | |
<tr> | |
<xsl:attribute name="class"> | |
<xsl:choose> | |
<xsl:when test="../@category = 'IT' or ../../@category = 'IT'"> | |
it | |
</xsl:when> | |
<xsl:otherwise> | |
math | |
</xsl:otherwise> | |
</xsl:choose> | |
</xsl:attribute> | |
<td> | |
<xsl:value-of select="$person"/> | |
</td> | |
<td> | |
<xsl:value-of select="../@title"/> | |
</td> | |
<td> | |
<xsl:value-of select="name(..)"/> | |
</td> | |
<td> | |
<xsl:value-of select="count(../bk:AuthorReference)-1"/> | |
</td> | |
</tr> | |
</xsl:for-each> | |
</xsl:for-each> | |
</table> | |
</xsl:template> | |
<xsl:template name="items"> | |
<table> | |
<tr> | |
<th>Category</th> | |
<th>Type</th> | |
<th>Price</th> | |
</tr> | |
<xsl:for-each select="bk:Books/bk:Book | bk:Journals/bk:Journal"> | |
<xsl:sort select="@price" data-type="number" order="descending"/> | |
<tr> | |
<td> | |
<xsl:value-of select="@category"/> | |
</td> | |
<td> | |
<xsl:value-of select="name(current())"/> | |
</td> | |
<td> | |
<xsl:value-of select="@price"/> | |
</td> | |
</tr> | |
</xsl:for-each> | |
</table> | |
</xsl:template> | |
</xsl:stylesheet> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// XSD schema | |
/* | |
In order to create a C# class from the schema paste the following into Pre-build events: | |
"$(SolutionDir)packages\Codaxy.Xsd2.0.9.9\tools\Xsd2.exe" "$(ProjectDir)Bookstore.xsd" /ns:Bookstore | |
Defining keys in schema (namespace is necessary) | |
<xs:key name="PERSON_ID"> | |
<xs:selector xpath="b:People/b:Person" /> | |
<xs:field xpath="@id" /> | |
</xs:key> | |
<xs:keyref name="ATHBK_PERSON_ID" refer="b:PERSON_ID"> | |
<xs:selector xpath="b:Books/b:Book/b:AuthorReference" /> | |
<xs:field xpath="@ref" /> | |
</xs:keyref> | |
<xs:keyref name="ATHART_PERSON_ID" refer="b:PERSON_ID"> | |
<xs:selector xpath="b:Journals/b:Journal/b:Article/b:AuthorReference" /> | |
<xs:field xpath="@ref" /> | |
</xs:keyref> | |
*/ | |
// Deserialization and validation against a schema file | |
using System.Xml.Linq; | |
using System.Xml.Schema; | |
using System.Xml.Serialization; | |
public static Bookstore Create(string xmlFilename) | |
{ | |
string xmlData = Validate(xmlFilename); | |
XmlSerializer serializer = new XmlSerializer(typeof(Bookstore)); | |
return (Bookstore)serializer.Deserialize(new StringReader(xmlData)); | |
} | |
public static string Validate(string xmlFilename) | |
{ | |
string xsdData = File.ReadAllText("Bookstore.xsd"); | |
string xmlData = File.ReadAllText(xmlFilename); | |
XDocument document = XDocument.Parse(xmlData); | |
XmlSchemaSet schemaSet = new XmlSchemaSet(); | |
schemaSet.Add(XmlSchema.Read(new StringReader(xsdData), (o, e) => | |
{ | |
if (e.Exception != null) throw e.Exception; | |
})); | |
document.Validate(schemaSet, (o, e) => | |
{ | |
if (e.Severity == XmlSeverityType.Error) throw e.Exception; | |
}); | |
return xmlData; | |
} | |
// XSLT transformation | |
using System.Xml.Xsl; | |
static void Main(string[] args) | |
{ | |
foreach (var arg in args) | |
{ | |
try | |
{ | |
Bookstore.Bookstore.Validate(arg); | |
XslCompiledTransform transform = new XslCompiledTransform(); | |
transform.Load("Bookstore.xslt"); | |
transform.Transform(arg, arg.Replace(".xml",".html")); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine(ex.Message); | |
} | |
} | |
} | |
// JSON serialization | |
using Newtonsoft.Json; | |
string authorsAsJSON = JsonConvert.SerializeObject(new | |
{ | |
authors = bookstore.People.Select(person => | |
new | |
{ | |
name = person.Name, | |
surname = person.Surname, | |
publications = bookstore.Publications.Where(pub => pub.AuthorReferenceID | |
.Contains(person.id)) | |
.Select(pub => new { title = pub.title }) | |
}) | |
}, Formatting.Indented); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:shop="http://www.mini.pw.edu.pl/~poLab/" | |
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" | |
> | |
<xsl:output method="html" indent="yes"/> | |
<xsl:template name="Product"> | |
<td> | |
<xsl:number value="position()"/> | |
</td> | |
<td> | |
<xsl:value-of select="shop:Name"/> | |
</td> | |
<td> | |
<xsl:value-of select="format-number(shop:Price, '###,###.##')"/> | |
</td> | |
</xsl:template> | |
<xsl:template match="shop:Product1"> | |
<tr> | |
<xsl:choose> | |
<xsl:when test="position() mod 4 = 1"> | |
<xsl:attribute name="style"> | |
background-color: cornflowerblue; | |
</xsl:attribute> | |
</xsl:when> | |
<xsl:otherwise> | |
<xsl:attribute name="style"> | |
background-color: gainsboro; | |
</xsl:attribute> | |
</xsl:otherwise> | |
</xsl:choose> | |
<xsl:call-template name="Product" /> | |
<td> | |
<xsl:value-of select="shop:Length"/> | |
</td> | |
<xsl:variable name="type" select="shop:ProductType" /> | |
<td> | |
<xsl:value-of select="$type"/> | |
</td> | |
<td> | |
<xsl:choose> | |
<xsl:when test="contains($type, 'A') or contains($type, 'B')"> | |
Yes | |
</xsl:when> | |
<xsl:otherwise> | |
No | |
</xsl:otherwise> | |
</xsl:choose> | |
</td> | |
</tr> | |
</xsl:template> | |
<xsl:template match="shop:Product2"> | |
<tr> | |
<xsl:call-template name="Product" /> | |
<td> | |
<xsl:value-of select="shop:Weight"/> | |
</td> | |
</tr> | |
</xsl:template> | |
<xsl:template match="/shop:Shop"> | |
<html> | |
<head> | |
<title>Shop</title> | |
</head> | |
<body> | |
<div> | |
<h1>Product1</h1> | |
<table border="1"> | |
<tr> | |
<th>Row</th> | |
<th>Name</th> | |
<th>Price</th> | |
<th>Length</th> | |
<th>Product Type</th> | |
<th>A or B</th> | |
</tr> | |
<tbody> | |
<xsl:apply-templates select="shop:Product1"> | |
<xsl:sort select="shop:Price"/> | |
</xsl:apply-templates> | |
</tbody> | |
</table> | |
</div> | |
<div> | |
<h1>Product2</h1> | |
<table border="1"> | |
<tr> | |
<th>Row</th> | |
<th>Name</th> | |
<th>Price</th> | |
<th>Weight</th> | |
</tr> | |
<tbody> | |
<xsl:apply-templates select="shop:Product2"/> | |
</tbody> | |
</table> | |
</div> | |
<div> | |
<h1>Static counter</h1> | |
<table border="1"> | |
<tr> | |
<th>Product type</th> | |
<th>Count</th> | |
</tr> | |
<tbody> | |
<tr> | |
<td>A</td> | |
<td> | |
<xsl:value-of select="count(shop:Product1[shop:ProductType = 'A'])"/> | |
</td> | |
</tr> | |
<tr> | |
<td>B</td> | |
<td> | |
<xsl:value-of select="count(shop:Product1[shop:ProductType = 'B'])"/> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
<div> | |
<h1>Dynamic counter</h1> | |
<table border="1"> | |
<tr> | |
<th>Product type</th> | |
<th>Count</th> | |
</tr> | |
<tbody> | |
<xsl:for-each select="shop:Product1/shop:ProductType[not(.=preceding::*)]"> | |
<tr> | |
<td> | |
<xsl:value-of select="."/> | |
</td> | |
<td> | |
<xsl:value-of select="count(//shop:Product1[shop:ProductType = current()])" /> | |
</td> | |
</tr> | |
</xsl:for-each> | |
</tbody> | |
</table> | |
</div> | |
</body> | |
</html> | |
</xsl:template> | |
</xsl:stylesheet> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment