아래의 내용은 SmallTool ver 1,0,0,8부터 방식이 변경되었습니다.
다음의 URL을 참조하십시오.
/Default.aspx?mode=2&sub=3&pageno=0&detail=1&wid=31
지난번 토픽에 이어서 진행하도록 하겠습니다.
TFSAddItemT를 정의했었는데요.
그 ComplexType에 Enum 형을 갖는 속성을 하나 추가해 보도록 하겠습니다.
그렇다면 우선 Enum Type부터 정의를 해야할 텐데요.
보통 XSDObjectGen.exe를 위해 다음과 같이 Single Type으로 정의를 합니다.
<xs:simpleType name="ProtocolEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="HTTP" />
<xs:enumeration value="HTTPS" />
</xs:restriction>
</xs:simpleType>
위와 같이 정의된 것을 VS.NET 2005에서 제공하는 XSD Designer로 보면, 다음 화면과 같습니다.
물론, 이렇게 했을 때 문제점이 있습니다.
Enum 값의 Serialize 결과가 문자열로 되어버린다는 것이죠. 더군다나 Database 같은 경우, 값을 저장할 때 보통 숫자값으로 저장을 한다는 점과, 그 숫자값이 연속적인 값이 아닐 수도 있다는 예외 상황이 있습니다.
예를 들어, 우리가 흔히 C++에서 정의했던 enum은 다음과 같은 경우도 많은데요.
typedef enum tagProtocolEnum
{
HTTP = 80,
HTTPS = 443
} ProtocolEnum;
위와 같은 구조로 Enum 형을 처리하는 것을 현재의 XSDObjectGen.exe는 지원하지 않고 있습니다.
그렇다고 손놓고, XSDObjectGen.exe가 업데이트될 때까지 기다리기도 지루하죠. ^^
자... 어쩔 수 없습니다. 소스를 수정하는 수밖에.
참고로, 여러분 스스로 소스를 확장할 수 있도록 다음의 토픽에 소스를 올려두었습니다.
XSDObjectGen 1.4.2.1 - 커스터마이징
;
/Default.aspx?mode=2&sub=3&pageno=0&detail=1&wid=23
일단, XSDObjectGen.exe의 소스를 수정하는 것은 어떻게든 해보겠지만.
문제는 XSD Schema 정의에서 "표준"을 벗어나서는 안된다는 제약이 있습니다. 다행히도 Enum을 처리하는 데에는 표준을 벗어나지는 않을 수 있었는데요. 바로 다음과 같이 xs:enumeration의 "id" 속성을 활용하는 것입니다.
그래서, 아래와 같이 변경할 수 있었습니다.
<xs:simpleType name="ProtocolEnum">
<xs:restriction base="xs:short">
<xs:enumeration id="HTTP" value="80" />
<xs:enumeration id="HTTPS" value="8080" />
</xs:restriction>
</xs:simpleType>
소스 수정은, ... 이미 된 것을 SmallTool에 반영시켜 놓았으니, SmallTool 1.0.0.4 버전 이상을 클라이언트에 설치하시면 됩니다.
이전에 설명해 드린 것처럼, "STXSDObjectGen" custom tool을 속성창에 정의해 놓았다면, 위와 같이 XSD를 변경하고 "저장"을 하는 순간, DataTypes.cs 파일이 자동으로 바뀌게 됩니다.
바뀐 소스를 한번 살펴 볼까요? ^^
[Serializable]
public enum ProtocolEnum
{
[XmlEnum(Name="80")] HTTP = 80,
[XmlEnum(Name="8080")] HTTPS = 8080,
}
우와... 우리가 원한 대로 나온 것 같습니다.
위와 같이 정의된 것을 VS.NET 2005에서 제공하는 XSD Designer로 보면, 다음 화면과 같습니다.
이제 위의 화면에서 정의된 TFSAddItemT 클래스를 인스턴스화하고, XML Serialization을 해보면,
------ cs 코드 -------
WinFormApp.Data.TFSAddItemT item = new WinFormApp.Data.TFSAddItemT();
item.Port = 8070;
item.Name = "Win2003";
item.Protocol = WinFormApp.Data.ProtocolEnum.HTTP;
StringWriter sw = new StringWriter();
XmlSerializer xs = new XmlSerializer(typeof(WinFormApp.Data.TFSAddItemT));
xs.Serialize(sw, item);
string txt = sw.ToString();
MessageBox.Show(txt);
MessageBox 결과, 다음과 같은 문자열로 직렬화된 것을 확인할 수 있습니다.
<?xml version="1.0" encoding="utf-16"?>
<TFSAddItemT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
Name="Win2003" Port="8070" Protocol="80" />
Enum 문제는 이걸로 해결되었습니다. ^^
첨부된 파일은 위에서 사용된 예제 솔루션 파일입니다.
간단한 XSD 파일을 포함하고 있습니다. 물론, 정상적인 XSD 소스 생성을 테스트해 보기 위해서는 SmallTool을 설치하셔야 합니다.