Microsoft MVP성태의 닷넷 이야기
사용 사례 : 7. 스키마 상속 처리 (3) [링크 복사], [링크+제목 복사]
조회: 2399
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

자, 이제 제가 진짜 원했던 XSDObjectGen.exe 확장 기능을 소개해야 겠습니다.
이것만 되면, 이젠 XSDObjectGen.exe에서 손을 놔도 될 것 같다는 생각이 드는데요. ^^

그런데, 지난 토픽에서 다룬 것을 보셨듯이 문제가 그리 간단하지 않습니다.
이전 토픽에서 3가지 문제를 제시해 드렸죠.

하나씩 풀어가보도록 하겠습니다.

우선, 첫 번째 문제점. 2번의 입력을 받아들이는 것을 자동화해야 하는 부분인데요.
다시 문제를 상기시키는 차원에서 아래에 그대로 복사해 보았습니다.

Imported namespaces were found.  Please enter valid .NET namespace names for each namespace.
WARNING. Namespaces chosen must not conflict with types and element names from the schemas.

Xsd namespace = https://www.sysnet.pe.kr/DerivedSchema.xsd. 
Please enter a CLR namespace name for this namespace: DerivedLib  <=== 입력된 부분

Xsd namespace = https://www.sysnet.pe.kr/DataTypes.xsd. 
Please enter a CLR namespace name for this namespace: DataTypesLib   <=== 입력된 부분
Done.
 Writing file DerivedLib.cs.
 Writing file DataTypesLib.cs.

아시겠지만, 2개 중에 하나, 즉 DerivedSchema.xsd에 대해서는 이미 명령행에서 /n: 파라미터를 통해서 주기 때문에, 굳이 다시 받아야 할 필요는 없습니다.
그럼, 인자 한 번의 입력은 생략해도 되겠고요.

문제는 2번째 인자로, import를 통해서 참조하고 있는 스키마가 .NET Code로 생성될 때 가져야 할 네임스페이스를 정해 주어야 하는 문제입니다. 고민 고민하다가, 이 부분은 해당 import 되는 xsd 스키마 파일 스스로가 자신의 .NET Code에 대한 네임스페이스를 정해주는 것으로 판단을 내렸습니다. 또한, 그걸 위해서 XSD 스키마를 임의로 확장할 수는 없기 때문에, 이번에도 enum 처리 때와 마찬가지로 xs:annotation의 힘을 빌리기로 했습니다. 그래서, DataTypes.xsd에는 다음과 같은 annotation 부분을 포함하고 있어야 합니다.

  <xs:annotation>
    <xs:documentation source="https://www.sysnet.pe.kr/DataTypes.xsd">WinForm.App</xs:documentation>
  </xs:annotation>

자신의 XSD 스키마 네임스페이스를 source 속성으로 지정하고, innerText에다가 .NET Code에 대한 네임스페이스를 지정하는 것입니다. annotation을 읽어서 처리하는 부분에 대해서는 XSDObjectGen.exe의 소스를 고치면 그만이므로, 그 정도는 일도 아니겠지요. 그럼, 첫 번째 문제는 이것으로 해결이 되었군요.

두 번째 문제점으로 넘어가서, XSD 파일 2개 생성인데요.
역시 이 부분도 XSDObjectGen.exe의 소스를 수정하는 것을 끝을 봤습니다.

마지막으로, 세 번째 문제점.

이것도 결국 소스 수정으로 끝났지만. 그것으로 인해 XSD가 소스로 바뀌는 과정에서 기존과 어떻게 달라졌는지 설명을 해야 할 것 같습니다.

일단, XSD 파일들이 Schema 네임스페이스는 다음과 같이 가지고 있게 됩니다.
즉, 모든 XSD 파일들이 고유한 네임스페이스를 가지게 됩니다.

DataTypes.xsd     : targetNamespace="https://www.sysnet.pe.kr/DataTypes.xsd" 
DerivedSchema.xsd : targetNamespace="https://www.sysnet.pe.kr/DerivedSchema.xsd" 

하지만, 스키마 네임스페이스가 다르다고 해서 .NET 소스 코드의 네임스페이스까지 달라져야 한다는 원칙은 있어서는 안 됩니다. 예를 들어, 위의 XSD 파일이 하나의 폴더에 같이 있다면, 2개 모두 동일하게 "WebLib.Data"라는 코드 네임스페이스를 가질 수 있다는 것입니다.

그런데, 기존 XSDObjectGen.exe는 스키마 상속을 처리할 때 .NET 소스 코드의 네임스페이스가 같아지면 문제가 발생하는 곳이 있습니다.
바로 Declarations 클래스의 SchemaVersion 상수 필드가 이름이 동일하다는 것이 그 문제입니다.

DataTypes.xsd를 처리한 DataTypes.cs 파일과, DerivedSchema.xsd를 처리한 DerivedSchema.cs 파일에는 각각 다음과 같은 클래스 파일이 들어가게 됩니다.

========= DataTypes.cs ===========
namespace WebLib.Data
{
    public partial class Declarations
    {
	public const string SchemaVersion = "https://www.sysnet.pe.kr/DataTypes.xsd";
    }
}
========= DerivedSchema.cs ===========
namespace WebLib.Data
{
    public partial class Declarations
    {
	public const string SchemaVersion = "https://www.sysnet.pe.kr/DerivedSchema.xsd";
    }
}

동일한 네임스페이스에, 같은 클래스명까지는 좋습니다. 왜냐하면, 지난번에 처리했던 partial 키워드의 추가 덕분입니다. 그런데, 동일한 클래스명에 SchemaVersion 필드가 2개가 정의되어져 있습니다. 당연히 컴파일러로 하여금 오류를 발생시키게 합니다.

어떻게 처리해야 할지 고민을 좀 했습니다. 클래스 이름을 개별적으로 가는 것은 별로 바람직하지 않을 것 같았습니다. 왜냐하면, 같은 클래스 우산 아래, 스키마 버전에 대한 필드들이 모여있는 것이 좋다고 판단했기 때문입니다. 그렇다면 남은 방법은 SchemaVersion 필드를 구분짓게 해야 했는데요. 여기서 또 고민입니다. 과연 어떤 문자열을 덧붙여서 유일성을 보장해 줄 것인가?

아무리 생각해도, 스키마 버전 변수에 할당된 네임스페이스 문자열 자체가 유일성을 보장해 줄 "유일"한 해결책으로 보였습니다. 마침, XSDObjectGen.exe 소스에서도, ScrubNamespace라는 함수를 제공해 주고 있는데요. "https://www.sysnet.pe.kr/DerivedSchema.xsd"와 같은 문자열을 .NET 언어의 variable 규칙에 어긋나지 않게 "http___www_sysnet_pe_kr_DerivedSchema_xsd" 이렇게 변경을 시켜주는 함수입니다.

그래서, 위에서 살펴본 코드는, SmallTool 1,0,0,8부터는 다음과 같은 코드로 바뀌어서 생성되게 됩니다.

========= DataTypes.cs ===========
namespace WebLib.Data
{
    public partial class Declarations
    {
	public const string SchemaVersion_http___www_sysnet_pe_kr_DataTypes_xsd = "https://www.sysnet.pe.kr/DataTypes.xsd";
    }
}
========= DerivedSchema.cs ===========
namespace WebLib.Data
{
    public partial class Declarations
    {
	public const string SchemaVersion_http___www_sysnet_pe_kr_DerivedSchema_xsd = "https://www.sysnet.pe.kr/DerivedSchema.xsd";
    }
}

자... 이걸로, 적어도 제가 사용하는 데 불편할 정도의 문제점들은 다 해결이 된 것 같습니다.
그럼, 여러분들도 이제 마음 편히, Data Contract를 먼저 설계하는 방식으로 이전해 보시기 바랍니다.
(물론, SmallTool에서 제공되는 XSDObjectGen.exe를 업무에 적용하시다가 불편한 점이나 개선점이 있다면 언제든지 의견 주십시오.)


첨부된 파일은 스키마 상속이 되고 있는 위의 예제 파일들을 담고 있는 솔루션 파일입니다.
실제로 코드가 어떻게 생성되는지도 테스트해 보실 수 있고, 나름대로의 스키마 정의를 해보실 수 있습니다.






[최초 등록일: ]
[최종 수정일: 6/26/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




[1]  2 
NoWriterDateCnt.TitleFile(s)
37정성태6/7/2016728MSBuild Structured Log: record and visualize your builds
36정성태10/20/20062997SmallTool ver 1.0.1.2 - 변경된 점
34정성태7/27/20062387SmallTool ver 1.0.1.1 - 변경된 점
35정성태7/27/20062297    답변글 SourceGDN].0.060717.001 - 변경된 소스파일 다운로드1
33정성태7/24/20062377SmallTool ver 1.0.1.0 - 변경된 점.
32정성태6/30/20062399사용 사례 : 7. 스키마 상속 처리 (3)
30정성태6/27/20063147사용 사례 : 6. 스미카 상속 처리 (2)
29정성태6/27/20062182사용 사례 : 5. ConsoleBat.exe - Path가 설정되어 있는 Command 창 이용하기
28정성태6/27/20062611사용 사례 : 4. 스미카 상속 처리 (1)파일 다운로드1
27정성태6/27/20062480사용 사례 : 3. XSDObjectGen - partial class 생성파일 다운로드1
26정성태6/29/20062324사용 사례 : 2. XSDObjectGen - Enum 처리에 대한 기능 향상파일 다운로드1
31정성태6/29/20062466    답변글 사용 사례 : 2.1 XSDObjectGen - Enum 처리 방식 변경
25정성태6/23/20062846사용 사례 : 1. VS.NET 통합 환경에서 XSDObjectGen 실행
24정성태6/23/20062343자동 로그인 ver 1.53파일 다운로드1
22정성태6/18/20062430ST : XSDObjectGen 1.4.2.1 포함
23정성태6/18/20062414    답변글 XSDObjectGen 1.4.2.1 - 커스터마이징파일 다운로드1
20정성태1/4/20073571ST: NDoc 2.0 한글 지원 버전
21정성태5/26/20062822    답변글 [답변]: ST: NDoc 2.0 한글 지원 버전 (업데이트)
19정성태5/18/20064123ST: ROBOCOPY.exe
18정성태4/20/20062561자동 로그인 ver 1.52 [2]파일 다운로드1
11정성태2/14/20047143폴더 백업( 동기화 ) 프로그램 [5]파일 다운로드1
7정성태7/24/20033040IExtender : Internet Explorer 확장툴 [2]
8정성태8/4/20032446    답변글 제거방법
6정성태7/23/20035343성태의 사이트 로그인 보안 구현: SysnetLogin
5정성태12/24/20043493성태의 게시판 구현이론: SysnetBoard
[1]  2