Pergunta

A resposta XML que recebo é a seguinte:

<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>

A minha turma é decorado como tal:

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

Quando tento desserializar o XML acima para a classe descrita, recebo um erro de "Namespace prefixo 'java' não está definido". Adicionando o atributo "namespace" para a classe resolve o erro de análise (no entanto, o XML é então distorcida do original).

ie

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

Como eu deveria estar decorando uma determinada propriedade para corresponder-se com um novo namespace? Ou, como faço para definir corretamente o namespace?

Eu não estou 100% sobre o uso de uma matriz de ações para minha seção enumeráveis ??quer, mas eu acho que a questão namespace leva precident no momento. Qualquer insight ou pensamentos são muito apreciados!

UPDATE:

Eu acho que a questão é melhor reformulada agora que eu voltar se foi e para trás um pouco:

Como você usa um XmlElementAttribute (ou outro atributo) para ter uma classe que pode serializar para o item trecho acima, incluindo as marcas XSI?

Como para o meu problema particular, eu realizei desde que a resposta XML é fora do meu controle, eu não preciso dos atributos xsi para começar. Para solucionar o problema serialização Estou apenas fazendo o seguinte (elemento XmlElement contém o documento original acima):

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

Eu estou apenas observando a minha solução pessoal como este não é realmente uma solução.

Foi útil?

Solução

Infelizmente este é um XML válido, e completamente em conformidade com o padrão XML. É valida, é correto e é completa.

O problema que você está tendo é na desserialização, que não é uma parte do padrão XML e está relacionado com tipos XML como .NET mapas declarados para tipos CLR internos.

O xsi: type é uma referência ao namespace e destina-se a permitir que documentos XML para substituir um tipo de derivado de outro namespace para o tipo declarado no esquema.

Eu sei da minha própria experiência que programadores tendem a reagir em estado de choque que este tipo de coisa é mesmo legal, XML muito menos correto. Ele basicamente seqüestra seu esquema.

Você não precisa sequer precisa incluir o namespace estrangeira para que esta seja considerada correta.

(veja este artigo para mais ranting sobre este assunto: http: // Norman. walsh.name/2004/01/29/trainwreck )

Agora, sobre a forma de lidar com o seu problema declarou: desserializar essa bagunça. 1) processar o texto XML e remover a declaração xsi-tipos e espero que não existem campos declarados que se estendem do tipo base. 2) declarar um tipo que deriva de seu tipo base no esquema.

Este parece ser o seguinte:

// 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 
{
...
}

Este é apenas um esboço, espero que o suficiente para você começar. Note-se que este não é um problema fácil de resolver progmatically porque é sempre possível para alguém para alimentá-lo XML e irá validar, mas não desserializar corretamente.

Outras dicas

Você estava certo da primeira vez. "Java" não é um espaço de nomes. É um prefixo namespace. Isso é uma abreviação do namespace, para uso no XML. Caso contrário, o namespace real teria que ser repetido sempre que você vê atualmente "java:".

Você pode usar List<Item> vez de Item[].

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top