2010-03-04 3 views
1
내가 C 번호로 직렬화하는 다음과 같은 형식으로 XML을 포함하는 스트림을 가지고

XmlReader가 각 요소에 네임 스페이스 URI를 추가하는 이유는 무엇입니까?

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<OrganisationMetaData xmlns="urn:organisationMetaDataSchema"> 
    <Organisations> 
    <Organisation> 
     <Code>XXX</Code> 
     <Name>Yyyyyy</Name>... 

내가 문자열 배의 하중을 수행했지만, 스트림과 친절 네임 스페이스를 추가한다 객체 속성을 모든 복잡한 요소에 적용합니다. 방금 xmlns 특성을 제거하고 스키마에 대해 유효성 검사를 잊어 버리면 빈 xmlns 특성이 추가됩니다. 내가 가진 문제는 XmlSerializer (?)의 Deserialize 메서드가 특성을 기대하지 않는다는 오류가 발생한다는 것입니다. XmlRoot 및 XmlType 특성을 사용하여 클래스를 꾸리려고했지만이 변경되지 않았습니다. 여기

내가이 사용 DataContractSerializer를 시도했습니다

public IList<Organisation> DeserializeOrganisations(Stream stream) 
    { 
     var serializer = new XmlSerializer(typeof(OrganisationMetaData)); 

     var mappingAssembly = //Resource in another assembly 

     var schemas = new XmlSchemaSet(); 
     schemas.Add(
      "urn:organisationMetaDataSchema", 
      XmlReader.Create(
       mappingAssembly.GetManifestResourceStream(
        // An xml schema 
        ) 
       ) 
      ); 
     var settings = new XmlReaderSettings() 
          { 
           ValidationType = ValidationType.Schema, 
           Schemas = schemas, 
           ValidationFlags = 
        XmlSchemaValidationFlags.ReportValidationWarnings 
          };    

     settings.ValidationEventHandler += settings_ValidationEventHandler; 
     var reader = XmlReader.Create(stream, settings); 

     var metaData= (OrganisationMetaData)serializer.Deserialize(reader); 
     return metaData.Organisations.ToList(); 
    } 

작업을 수행하는 데 사용되는 방법 내가 여기

[XmlRoot(
    ElementName = "OrganisationMetaData", 
    Namespace = "urn:organisationMetaDataSchema")] 
public class OrganisationMetaData 
{ 
    public List<Organisation> Organisations { get; set; } 
} 

[XmlType(
    TypeName = "Organisation", 
    Namespace = "urn:organisationMetaDataSchema")] 
public class Organisation 
{ 
    public string Code {get; set;} 

    public string Name {get; set;} 
} 

로 직렬화하는 클래스의입니다하지만 그것이 자신의 oppotunities의 제공 배우면 누구나 XmlSerializer가 작동하도록 속성에 넣어야하는 것을 도울 수 있다면 큰 도움이 될 것입니다.

감사합니다. 감사드립니다.

답변

0

내가 데이터 계약을 사용하는 코드를 변경 결국 serializer를 사용하면 스키마에 대해 XML 스트림의 유효성을 검사하는 판독기를 가질 수 있도록 네임 스페이스 주변에 더 분명한 오류가 발생했으며 스트림을 되감고 xml을 deserialize 한 다른 판독기에서 다시 사용하게되었습니다.

읽기 this question은 xml 요소가 사전 순으로 있어야하는 곳으로 알려졌습니다. 또한 열거 형인 클래스의 속성을 deserialize 할 때이 속성이 존재하도록 요구해야합니다 (결국 nullable이 아님).

그런 다음 일부 값이 생략 된 XML 노드 (스키마에 의해 확인 됨)가있는 다른 오류가 발생했지만 데이터 계약에서이 값이 순서대로 있어야하므로 명시 적으로 지정해야했습니다.

나는이보고 시간을내어 마크이

[DataMember(
     Name = "MyEnumType", 
     EmitDefaultValue = false, 
     IsRequired = true, 
     Order = 3)] 
//Just assume I added this prop after my Code, and Name properties from above 

덕분에 같은 속성 데이터 멤버와 함께했다.

1

여기서 핵심은 [XmlRoot]이 클래스와 같은 루트 유형에만 적용될 수 있다는 것입니다. List<>을 루트로 사용하는 경우 작동하지 않습니다.하지만 [XmlElement]으로 그 값을 줄일 수 있습니다. 나는 (Encoding.UTF8 통해) Stream 방법을 사용하지만,이 정말 IMO 문제의 핵심 아님을 유의하고 있습니다 (루트 유형입니다) :

[XmlRoot(Namespace="urn:organisationMetaDataSchema")] 
public class Organisations 
{ 
    private readonly List<Organisation> items = new List<Organisation>(); 
    [XmlElement("Organisation")] 
    public List<Organisation> Items { get { return items; } } 

} 
public class Organisation 
{ 
    public string Code { get; set; } 
    public string Name { get; set; } 
} 
static class Program 
{ 
    static void Main() 
    { 
     string xml = @"<?xml version='1.0' encoding='utf-8' standalone='yes'?><Organisations xmlns='urn:organisationMetaDataSchema'><Organisation><Code>XXXX</Code><Name>YYYYYYYY</Name></Organisation></Organisations>"; 
     XmlSerializer ser = new XmlSerializer(typeof(Organisations)); 
     using (Stream input = new MemoryStream(Encoding.UTF8.GetBytes(xml))) 
     { 
      Organisations orgs = (Organisations)ser.Deserialize(input); 
     } 
    } 
} 
+0

감사합니다. 마크, 지금은 약간의 뇌가 퇴색하고 있습니다. 내 XML에는 문자열에있는 작은 따옴표가 없습니다. 어떻게 이것을 극복하겠습니까? 바꾸기 (...)와 같은 간단한 것입니까? –

+0

나는 여기에 대해 생각해 볼 수있는 모든 것을 시도했다. 약 8 시간 후에 DataContractSerializer 대신 포기하고 대신 동쪽에서 xml에 대해 마음에 들지 않는 것에 대해 조금 더 말해 줄 수있다. . 도와 줘서 고마워 마크 : –

+0

@ 마크 - 작은 따옴표는 중요하지 않습니다. 게시 된 코드는 사용자가 인용 한 xml을 deserialize해야합니다. 수업을 게시 할 수 있습니까 (또는 원하는 경우 전자 메일로 보낼 수 있습니까)? 나는 무엇이 잘못되었는지를 말할 수 있다고 확신한다 ... –

관련 문제