잊지 않겠습니다.

Pro LINQ (07)

Book 2009. 1. 15. 02:32
XML Schema(*.xsd)파일을 이용한 XML의 Validation과 기존의 XmlDocument에서 지원되는 XPath 역시 같이 지원 가능하다. 또한, 제공되는 XML을 통한 XML Schema를 역으로 얻어내는 방법을 같이 제공하고 있다. 

var xDocument = new XDocument();
var rootElement = new XElement("BookParticipants");

var bookElement1 = new XElement("BookParticipant");
bookElement1.Add(new XAttribute("type", "Author"));
bookElement1.Add(new XElement("FirstName", "Joe"));
bookElement1.Add(new XElement("LastName", "Rattz"));
rootElement.Add(bookElement1);

var bookElement2 = new XElement("BookParticipant");
bookElement2.Add(new XAttribute("type", "Editor"));
bookElement2.Add(new XElement("FirstName", "Ewan"));
bookElement2.Add(new XElement("LastName", "Buckingham"));
rootElement.Add(bookElement2);

xDocument.Add(rootElement);
xDocument.Save("bookparticipants.xml");

XmlSchemaInference infer = new XmlSchemaInference();
XmlSchemaSet schemaSet = infer.InferSchema(XmlReader.Create("bookparticipants.xml"));
XmlWriter xmlWriter = XmlWriter.Create("bookparticipants.xsd");

foreach(XmlSchema xmlSchema in schemaSet.Schemas())
{
    xmlSchema.Write(xmlWriter);
}
xmlWriter.Close();

XDocument schemaDocument = XDocument.Load("bookparticipants.xsd");
Console.WriteLine(schemaDocument);

정말로 대단한 기능이라고 생각이 되는 것이, XML 파일만 있더라고 그 안에서 XSD의 추론이 가능해지기 때문에, 그 응용을 어떤 방향으로 솔찍히 해줘야지 될지 잘은 모르겠다는 생각이 든다. 아직 XSD를 잘 사용을 안하고 있는 것이 잘 모르고 있는 이유중 하나일 것 같다.

XML의 Validation은 다음과 같이 할 수 있다. 기존의 XmlDocument와 코드가 완전히 동일하다.
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.Add(string.Empty, "bookparticipants.xsd");
try
{
    xDocument.Validate(schemaSet, null);
    Console.WriteLine("Document validated successfully");
}
catch(XmlSchemaValidationException ex)
{
    Console.WriteLine(ex.Message);
}


마지막으로 XDocument에서의 XPath 사용을 간략한 예이다.
xDocument.Add(rootElement);
XElement xElement = xDocument.XPathSelectElement("//BookParticipants/BookParticipant[FirstName='Joe']");
Console.WriteLine(string.Format("Selected Element : {0} / {1}", xElement.Name, xElement.Value));




Posted by Y2K
,
public ContentResult ConvertJoinOrLeaveReasonsToContentResult(IQueryable<JoinOrLeaveReason> joinOrLeaveReasons, string fileName)
{
    string attachment = string.Format("attachment; filename={0}", fileName);

    Response.ClearContent();
    Response.AppendHeader("content-disposition", attachment);
    Response.Buffer = true;
    Response.Charset = string.Empty;

    TableStyle tblStyle = new TableStyle();
    tblStyle.BorderStyle = BorderStyle.Solid;
    tblStyle.BorderColor = Color.Black;
    tblStyle.BorderWidth = Unit.Parse("1px");

    TableItemStyle headerStyle = new TableItemStyle();
    headerStyle.BackColor = Color.LightGray;

    StringWriter sw = new StringWriter();
    HtmlTextWriter tw = new HtmlTextWriter(sw);

    tblStyle.AddAttributesToRender(tw);
    tw.RenderBeginTag(HtmlTextWriterTag.Table);

    tw.RenderBeginTag(HtmlTextWriterTag.Thead);
    {
        headerStyle.AddAttributesToRender(tw);
        tw.RenderBeginTag(HtmlTextWriterTag.Th);
        tw.Write("Date");
        tw.RenderEndTag();

        headerStyle.AddAttributesToRender(tw);
        tw.RenderBeginTag(HtmlTextWriterTag.Th);
        tw.Write("Comment");
        tw.RenderEndTag();
    }
    tw.RenderEndTag();

    Encoding encoding = sw.Encoding;
    tw.RenderBeginTag(HtmlTextWriterTag.Tbody);
    foreach(JoinOrLeaveReason joinOrLeaveReason in joinOrLeaveReasons)
    {
        tw.RenderBeginTag(HtmlTextWriterTag.Tr);
        {
            tw.RenderBeginTag(HtmlTextWriterTag.Td);
            tw.Write(string.Format("{0:yyyy-MM-dd HH:mm:ss}", joinOrLeaveReason.CreateDate));
            tw.RenderEndTag();

            tw.RenderBeginTag(HtmlTextWriterTag.Td);
            tw.Write(string.Format("{0}", joinOrLeaveReason.Comment));
            tw.RenderEndTag();
        }
        tw.RenderEndTag();
    }
    tw.RenderEndTag();

    tw.RenderEndTag();

    ContentResult contentResult = new ContentResult();
    contentResult.ContentType = "application/ms-excel";
    contentResult.Content = sw.ToString();
    contentResult.ContentEncoding = Encoding.UTF8;

    return contentResult;
}

1. Response 설정 : Header, Buffer 설정
2. ContextResult의 데이터 설정
 - HtmlTextWriter를 이용한 Table Build
 - Table의 속성은 Attribute를 이용해서 설정해준다. 
3. 최종적으로 Context를 TextWriter를 이용해서 얻어준다.
Posted by Y2K
,
ActionResult의 Type중 ContentResult를 이용한다. 

먼저, Response 에 Buffer 설정과 Header 설정을 한다.
            Response.ClearContent();
            Response.AppendHeader("content-disposition", attachment);
            Response.Buffer = true;

다음 ContentResult의 결과를 넣어준다. 
<table>로 표현하는 경우에는 Excel에서 표로 읽는 것이 가능하다. 

            StringBuilder sb = new StringBuilder();
            sb.Append("<table>");
            sb.Append("<tr>");
            sb.Append("<td>Date</td>");
            sb.Append("<td>Comment</td>");
            sb.Append("</tr>");

            foreach(JoinOrLeaveReason joinOrLeaveReason in joinOrLeaveReasons)
            {
                sb.Append("<tr>");
                sb.AppendFormat("<td>{0:yyyy-MM-dd HH:mm:ss}</td>", joinOrLeaveReason.CreateDate);
                sb.AppendFormat("<td>{0}</td>", joinOrLeaveReason.Comment);
                sb.Append("</tr>");
            }
            sb.Append("</table>");

            ContentResult contentResult = new ContentResult();
            contentResult.ContentType = "application/wnd.ms-excel";
            contentResult.Content = sb.ToString();
            contentResult.ContentEncoding = Encoding.UTF8;

            return contentResult;

사용될 수 있는 Content-Type의 종류는 다음과 같다. 

1) Multipart Related MIME 타입
  - Content-Type : Multipart/related(기본형태)
  - Content-Type : Application/X-FixedRecord
  - Content-Type: Text/x-Okie; charset=iso-8859-1;

2) XML Media의 타입
 - Content-Type : text/xml
 - Content-Type : Application/xml
 - Content-Type : Application/xml-external-parsed-entity
 - Content-Type : Application/xml-dtd
 - Content-Type : Application/mathtml+xml
 - Content-Type : Application/xslt+xml

3) Application의 타입 
 - Content-Type : Application/EDI-X12:  Defined in RFC 1767 
 - Content-Type : Application/EDIFACT:  Defined in RFC 1767 
 - Content-Type : Application/javascript: Defined in RFC 4329 
 - Content-Type : Application/octet-stream: <-- 디폴트 미디어 타입은 운영체제 종종 실행파일, 다운로드를 의미
 - Content-Type : Application/ogg: Defined in RFC 3534 
 - Content-Type : Application/x-shockwave-flash: Adobe Flash files
 - Content-Type : Application/json: JavaScript Object Notation JSON; Defined in RFC 4627 
 - Content-Type : Application/x-www-form-urlencode <-- HTML Form 형태 

* x-www-form-urlencode와 multipart/form-data은 둘다 폼 형태이지만 x-www-form-urlencode은 대용량 바이너리 테이터를 전송하기에 비능률적이기 때문에 대부분 첨부파일은 multipart/form-data를 사용하게 된다. 

4) 오디오 타입
- Content-Type : Type audio: Audio 
- Content-Type : audio/mpeg: MP3 or other MPEG audio
- Content-Type : audio/x-ms-wma: Windows Media Audio;
- Content-Type : audio/vnd.rn-realaudio: RealAudio;  등등 
 

5) Multipart 타입(아카이브 또는 개체) 
- Content-Type : multipart/mixed: MIME E-mail; 
- Content-Type : multipart/alternative: MIME E-mail;
- Content-Type : multipart/related: MIME E-mail; Defined in RFC 2387 and used by MHTML(HTML mail) 
- Content-Type : multipart/formed-data : <-- 파일 첨부

6) TEXT 타입 
- Content-Type : text/css:  
- Content-Type : text/html:
- Content-Type : text/javascript 
- Content-Type : text/plain: 
- Content-Type : text/xml: 


7) 기타 MIMERPC 예제들 
가) HTTP with x/www-form-urlencoded 일반요청 
POST /some/resource HTTP/1.1
Content-type: application/x-www-form-urlencoded
0=example.getStateName&1=10023


[응답]
HTTP/1.1 200 OK
Content-type: text/plain
New York


나) HTTP x/www-form-urlencoded namedArgs getTeam
POST /some/resource HTTP/1.1
Content-type: application/x-www-form-urlencoded
0=example.getTeam&state=New York&sport=Baseball


[응답]
HTTP/1.1 200 OK
Content-type: multipart/mixed, boundary=B
--BYankees

--BMets

--B


다) HTTP x/www-form-urlencoded unicode addUser
POST /some/resource HTTP/1.1
Content-type: application/x-www-form-urlencoded
0=example.addUser&fname=Igna%ACio&lname=Sanchez


라) HTTP with multipart/form-data 요청
POST /some/resource HTTP/1.1
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="field1"


Joe Blow


--AaB03x  
content-disposition: form-data; name="pics"; filename="file1.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary
...contents of file1.gif...


--AaB03x--

[응답] 
HTTP/1.0 200 OK
Content-type: text/plain
OK


마) Uploading multiple files with unicode

POST /foo HTTP/1.0
Content-type: multipart/form-data, boundary=AaB03x


--AaB03x
content-disposition: form-data; name="field1"
Joe Blow


--AaB03x  <-- 여러개의 파일을 첨부할 때 
content-disposition: form-data; name="pics"
Content-type: multipart/mixed, boundary=BbC04y

--BbC04y  <-- 첫번째 첨부파일은 텍스트
Content-disposition: attachment; filename="file1.txt"
Content-Type: text/plain; charset=UNICODE-1-1
Content-Transfer-Encoding: binary
... contents of some unicode file.txt ...


--BbC04y <-- 두번째 첨부파일은 이미지
Content-disposition: attachment; filename="file2.gif"
Content-type: image/gifContent-Transfer-Encoding: binary
...contents of file2.gif...

--BbC04y


----AaB03x--


바) XML and EMail 요청
HTP Request 
POST /x/foo/bar HTTP/1.0
reply-to-url: callback@domain.com
message-id: abc123
aynch: required0=getAuthorization&1="bobjones"


[응답] 
HTTP/1.0 200 OK
delivered-to: callback@domain.com
Content-length: 0
Mail/SMTP Response 
To: callback@domain.comFrom: mimeRPC@otherplace.com
in-reply-to: abc123
content-type: text/xml
<?xml version="1.0"?><this><is /><xml /></this>

Posted by Y2K
,