2017-07-07 15 views
5

Nie mogę zrozumieć, dlaczego generatory kodu C# (xsd, xsd2code) generują klasę wyjściową Profil z dwiema właściwościami tego samego typu oznaczonymi różnymi atrybutami. Jeden z nich jest oznaczony jako Niekwalifikowany, a jeden nie.Klasa C# wygenerowana z XSD zawiera właściwości oznaczone różnymi atrybutami kwalifikacyjnymi

Moje XSD wygląda następująco:

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.acme.com" xmlns="http://www.acme.com" elementFormDefault="unqualified"> 
    <xsd:complexType name="ParameterList"> 
    <xsd:sequence> 
     <xsd:element ref="Parameter" minOccurs="0" maxOccurs="unbounded"/> 
    </xsd:sequence> 
    </xsd:complexType> 
    <xsd:complexType name="ParameterItem"> 
    <xsd:sequence> 
     <xsd:element name="Name" type="xsd:string" minOccurs="1" maxOccurs="1"/> 
     <xsd:element name="Value" type="xsd:string" minOccurs="1" maxOccurs="1"/> 
    </xsd:sequence> 
    </xsd:complexType> 
    <xsd:element name="Parameters" type="ParameterList" /> 
    <xsd:element name="Parameter" type="ParameterItem" /> 
    <xsd:element name="Profile"> 
    <xsd:complexType> 
     <xsd:sequence>   
     <xsd:element ref="Parameters" minOccurs="1" maxOccurs="1"/> 
     <xsd:element name="Parameters" type="ParameterList" minOccurs="1" maxOccurs="1"/>  
     </xsd:sequence> 
    </xsd:complexType> 
    </xsd:element> 
</xsd:schema> 

i wyjście kod generowany przez xsd2code:

using System.Collections.Generic; 
using System.Xml.Schema; 
using System.Xml.Serialization; 

namespace SO2_installation 
{ 
    public class ParameterList 
    { 
     public ParameterList() 
     { 
      Parameter = new List<ParameterItem>(); 
     } 

     public List<ParameterItem> Parameter { get; set; } 
    } 

    public class ParameterItem 
    { 
     public string Name { get; set; } 

     public string Value { get; set; } 
    } 

    public class Profile 
    { 
     public Profile() 
     { 
      Parameters1 = new List<ParameterItem>(); 
      Parameters = new List<ParameterItem>(); 
     } 

     [XmlArray(Order = 0)] 
     [XmlArrayItem("Parameter", IsNullable = false)] 
     public List<ParameterItem> Parameters { get; set; } 

     [XmlArray("Parameters", Form = XmlSchemaForm.Unqualified, Order = 1)] 
     [XmlArrayItem("Parameter", IsNullable = false)] 
     public List<ParameterItem> Parameters1 { get; set; } 
    } 
} 

Kod został uproszczony przez R #, więc nie jest to dokładny wyjście z xsd2code, ale pokazuje, co mnie martwi - dlaczego te dwie właściwości nie są oznaczone tymi samymi atrybutami?

Jest to problem podczas przygotowywania pliku XML zgodnego z XSD. Powinien wyglądać jak ten poniżej, co sprawia, że ​​przygotowanie jest bardzo podatne na błędy.

<?xml version="1.0" encoding="utf-8"?>      
<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Parameters xmlns="http://www.acme.com">  
     <Parameter xmlns="http://www.acme.com"> 
      <Name xmlns="">SERIALNUMBER</Name> 
      <Value xmlns="">600001</Value> 
     </Parameter>   
    </Parameters>  
    <Parameters1 xmlns=""> 
     <Parameter xmlns="http://www.acme.com"> 
      <Name xmlns="">SERIALNUMBER</Name> 
      <Value xmlns="">600002</Value> 
     </Parameter>   
    </Parameters1>   
</Profile> 

Odpowiedź na pytanie: „dlaczego dwie właściwości tego samego rodzaju, oparte na tej samej XSD są oznaczone różnymi atrybutami” nie jest moim głównym problemem. Ponieważ nie mogę zmienić plików XSD (zostały one wysłane do klientów dawno temu), muszę znaleźć sposób na sporządzanie plików XML bez względu na to, czy ich elementy są oznaczone obszarami nazw czy nie. Obecnie, kiedy mijam XML, na przykład:

<Parameters1 xmlns="http://www.acme.com"> 

XmlSerializer zwróci błąd parsowania. Byłoby miło wysłać XML z wszystkimi parametrami oznaczonymi przestrzenią nazw lub bez przestrzeni nazw - nie ma znaczenia, o ile będą konsekwentnie oznaczone.

Z góry dziękuję za pomoc w rozwiązaniu tego problemu.

Uwaga dodatkowa: przykład jest przygotowany do uproszczenia załączonego kodu, więc nie przejmuj się, że Profil składa się z dwóch właściwości tego samego rodzaju.

Odpowiedz

0

Powodem dwie właściwości są generowane jest:

elementFormDefault="unqualified"> 

co oznacza, że ​​wszystkie lokalne elementy XML nie powinna być kwalifikowana - powinny być kwalifikowane z pustych przestrzeni nazw xmlns = „”. Innymi słowy w kodzie danego fragmentu:

<xsd:element name="Profile"> 
    <xsd:complexType> 
     <xsd:sequence>   
     <xsd:element ref="Parameters" minOccurs="1" maxOccurs="1"/> 
     <xsd:element name="Parameters" type="ParameterList" minOccurs="1" 
      maxOccurs="1"/>  
     </xsd:sequence> 
    </xsd:complexType> 
</xsd:element> 

pierwsze parametry elementem jest odniesienie się do globalnego typu, które w XML mogą być kwalifikowane z nazw docelowej. Czemu? Ponieważ wszystkie elementy globalne powinny być kwalifikowane z docelową przestrzenią nazw bez względu na to, jaka jest wartość atrybutu elementFormDefault.

Drugi element to LOKALNA definicja nowego elementu Parametry, a ponieważ elementFormDefault = "unqualified" w XML, który będzie walidowany z tym xsd, istnieją dwa obowiązkowe elementy Parametery, kwalifikowane z różnymi przestrzeniami nazw.

Aby w pełni odpowiedzieć na twoje pytanie - nie widzę rozwiązania bez zmiany lub nadpisania definicji w twoim xsd. Jeśli elementy Paramters w oryginalnym pliku xsd mają atrybut minOccurs = "0", można je pominąć. Może redefinicja jest również opcją dla twojego przypadku biznesowego (https://www.w3schools.com/xml/el_redefine.asp).

Powiązane problemy