2009-07-29 7 views
3

는 다음과 내가받은 XML 응답이 될 때 :역 직렬화 된 XML은

<response> 
    <item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="java:com.someDomain.item"> 
     <name>some name</disc-name> 
     <description>some description</disc-desc> 
    </item> 
    <item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="java:com.someDomain.item"> 
      <name>some name</disc-name> 
      <description>some description</disc-desc> 
    </item> 
    <otherValue>12.1</otherValue> 
</response> 

내 클래스는 같은 장식 :

[XmlElement("item")] 
public Item[] Items{get;set;} 
[XmlElement("otherValue") 
public string OtherValue{get;set;} 

나는 위의 XML을 역 직렬화 시도 클래스 설명, "네임 스페이스 접두사 'java'정의되지 않았습니다"오류가 나타납니다. 클래스에 "네임 스페이스"특성을 추가하면 구문 분석 오류가 해결됩니다 (단, xml은 원본에서 왜곡됩니다).

[XmlElement(ElementName="item",Namespace="java")] 

어떻게 새로운 네임 스페이스와 일치하는 특정 속성을 장식해야 하는가? 또는 네임 스페이스를 올바르게 정의하려면 어떻게해야합니까?

열거 형 섹션에도 스톡 배열을 사용하는 것이 100 % 아니지만 지금은 네임 스페이스 문제가 발생하지 않는다고 생각합니다. 모든 통찰력 또는 생각은 크게 평가됩니다!

UPDATE :

나는 질문이 더 나는 앞뒤로 간으니 이제 고쳐 생각 비트 : 당신이 할 수있는 클래스를 가지고하는 XmlElementAttribute (또는 다른 속성을) 어떻게 사용합니까

xsi 태그를 포함하여 위의 항목 스 니펫으로 직렬화 하시겠습니까?

내 특정 문제에 관해서는 Xml 응답이 내 통제를 벗어 났으므로 깨달았습니다. xsi 특성이 필요하지 않습니다. 직렬화 문제를 해결하려면, 단순히 (원본 문서 위 XMLELEMENT 요소 포함) 다음과 같은 일을 해요 :

foreach(XmlNode node in element) 
node.Attributes.RemoveAll(); 

를이 실제로 해결책이 아니다 나는 단지 내 개인적인 해결 방법을 지적하고있다.

답변

0

불행히도이 XML은 유효하며 XML 표준을 완전히 준수합니다. 유효성 검사가 정확하고 완료되었습니다.

XML 표준의 일부가 아니며 .NET 맵에서 XML 유형을 내부 CLR 유형으로 선언하는 방법과 관련된 직렬화 복원에 문제가 있습니다.

xsi : type은 네임 스페이스 참조이며 XML 문서가 스키마에서 선언 된 유형의 다른 네임 스페이스에서 파생 된 유형으로 대체 할 수 있도록하기위한 것입니다.

필자는 경험 많은 코더들이 충격을 받아 반응하는 경향이 있음을 잘 알고 있습니다. 기본적으로 스키마를 탈취합니다.

올바른 것으로 간주되기 위해 외부 네임 스페이스를 포함 할 필요가 없습니다.

(이 주제에 대한 자세한 고함은이 문서를 참조하십시오 http://norman.walsh.name/2004/01/29/trainwreck를)

지금, 당신의 진술 문제를 처리하는 방법에 관해서는이 혼란을 역 직렬화. 1) xml 텍스트를 처리하고 xsi 유형 선언을 제거하고 기본 유형을 확장하는 선언 된 필드가 없기를 바랍니다. 2) 스키마의 기본 유형에서 파생 된 유형을 선언하십시오.

이는 다음과 같습니다

// note this "XmlIncludeAttribute" references the derived type. 
// note that in .NET they are in the same namespace, but in XML they are in different namespaces. 
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DerivedType))] 
[System.SerializableAttribute()] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://BaseNameSpace")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://BaseNameSpace", IsNullable=true)] 
public partial class MyBaseType : object 
{ 
... 
} 

/// <remarks/> 
[System.SerializableAttribute()] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://DerivedNameSpace")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://DerivedNameSpace", IsNullable=true)] 
public partial class DerivedType: MyBaseType 
{ 
... 
} 

이 시작하기 잘하면 충분히 대략적인 윤곽이다. 이것은 누군가가 여러분에게 XML을 제공 할 수 있고 유효성을 검사 할 수는 있지만 제대로 직렬화를 해제 할 수 없기 때문에 천천히 해결하는 것은 쉬운 문제가 아닙니다.

1

첫 번째로 옳았습니다. "java"는 네임 스페이스가 아닙니다. 이것은 네임 스페이스 접두사입니다. XML에서 사용하기 위해 네임 스페이스의 약어입니다. 그렇지 않으면 실제 네임 스페이스는 현재 "java :"가 표시되어있는 곳이면 어디서든 반복해야합니다.

Item[] 대신 List<Item>을 사용할 수 있습니다.

+0

"java"가 네임 스페이스로 나열되지 않은 것은 저에게 의미가 있습니다. 그러나 들어오는 XML 응답의 deserialization에서 "네임 스페이스 접두사 'java'가 정의되지 않았습니다."라는 오류가 나타납니다. –

+0

당신이 보여주지 않은 나머지 문서에 있다고 가정했습니다. 전체 XML 문서를 게시 할 수 있습니까? 'java :'가 정의되어 있지 않다면, 당신이 할 수있는 일은 아무것도 없다. 단지 잘못된 XML 일 뿐이다. –

+0

위의 샘플에는 여러 개의 "othervalues"가 추가되어 있지만 헤더 xml 버전 태그 이외의 전체 문서가 있습니다. 이것은 REST 응답으로 수신되고 있으므로 Xml을 제어 할 필요가 없으며 사용 가능한 개체로 변환하려고 시도합니다. –