diff --git a/catalog.go b/catalog.go index 96a70f95..90d72f8c 100644 --- a/catalog.go +++ b/catalog.go @@ -15,10 +15,10 @@ type Catalog struct { ListType ObjectTypeRef `xml:"listType"` ManagerType ObjectTypeRef `xml:"managerType"` } `xml:"producedTypes"` - Name string `xml:"name"` - Synonym ValueTypeRef `xml:"synonym"` - InputByString string `xml:"inputByString"` - FullTextSearchOnInputByString string `xml:"fullTextSearchOnInputByString"` + Name string `xml:"name"` + Synonym ObjectKeyValueType `xml:"synonym"` + InputByString string `xml:"inputByString"` + FullTextSearchOnInputByString string `xml:"fullTextSearchOnInputByString"` StandardAttributes []struct { DataHistory string `xml:"dataHistory"` Name string `xml:"name"` @@ -33,28 +33,28 @@ type Catalog struct { MaxValue struct { Type string `xml:"type,attr"` } `xml:"maxValue"` - FillFromFillingValue string `xml:"fillFromFillingValue"` - FillChecking string `xml:"fillChecking"` - ToolTip ValueTypeRef `xml:"toolTip"` + FillFromFillingValue string `xml:"fillFromFillingValue"` + FillChecking string `xml:"fillChecking"` + ToolTip ObjectKeyValueType `xml:"toolTip"` } `xml:"standardAttributes"` - CreateOnInput string `xml:"createOnInput"` - DataLockControlMode string `xml:"dataLockControlMode"` - FullTextSearch string `xml:"fullTextSearch"` - ObjectPresentation ValueTypeRef `xml:"objectPresentation"` - Hierarchical string `xml:"hierarchical"` - LevelCount string `xml:"levelCount"` - FoldersOnTop string `xml:"foldersOnTop"` - DescriptionLength string `xml:"descriptionLength"` - CodeType string `xml:"codeType"` - CodeAllowedLength string `xml:"codeAllowedLength"` - DefaultPresentation string `xml:"defaultPresentation"` - EditType string `xml:"editType"` - ChoiceMode string `xml:"choiceMode"` + CreateOnInput string `xml:"createOnInput"` + DataLockControlMode string `xml:"dataLockControlMode"` + FullTextSearch string `xml:"fullTextSearch"` + ObjectPresentation ObjectKeyValueType `xml:"objectPresentation"` + Hierarchical string `xml:"hierarchical"` + LevelCount string `xml:"levelCount"` + FoldersOnTop string `xml:"foldersOnTop"` + DescriptionLength string `xml:"descriptionLength"` + CodeType string `xml:"codeType"` + CodeAllowedLength string `xml:"codeAllowedLength"` + DefaultPresentation string `xml:"defaultPresentation"` + EditType string `xml:"editType"` + ChoiceMode string `xml:"choiceMode"` Attributes []struct { - Uuid string `xml:"uuid,attr"` - Name string `xml:"name"` - Synonym ValueTypeRef `xml:"synonym"` - Comment string `xml:"comment"` + Uuid string `xml:"uuid,attr"` + Name string `xml:"name"` + Synonym ObjectKeyValueType `xml:"synonym"` + Comment string `xml:"comment"` Type struct { Types string `xml:"types"` DateQualifiers string `xml:"dateQualifiers"` @@ -65,7 +65,7 @@ type Catalog struct { Length string `xml:"length"` } `xml:"stringQualifiers"` } `xml:"type"` - ToolTip ValueTypeRef `xml:"toolTip"` + ToolTip ObjectKeyValueType `xml:"toolTip"` MinValue struct { Type string `xml:"type,attr"` } `xml:"minValue"` @@ -79,14 +79,14 @@ type Catalog struct { Type string `xml:"type,attr"` Value string `xml:"value"` } `xml:"fillValue"` - Indexing string `xml:"indexing"` - FullTextSearch string `xml:"fullTextSearch"` - Use string `xml:"use"` - DataHistory string `xml:"dataHistory"` - Format ValueTypeRef `xml:"format"` - EditFormat ValueTypeRef `xml:"editFormat"` - Mask string `xml:"mask"` - MultiLine string `xml:"multiLine"` + Indexing string `xml:"indexing"` + FullTextSearch string `xml:"fullTextSearch"` + Use string `xml:"use"` + DataHistory string `xml:"dataHistory"` + Format ObjectKeyValueType `xml:"format"` + EditFormat ObjectKeyValueType `xml:"editFormat"` + Mask string `xml:"mask"` + MultiLine string `xml:"multiLine"` } `xml:"attributes"` TabularSections []struct { Uuid string `xml:"uuid,attr"` @@ -94,9 +94,9 @@ type Catalog struct { ObjectType ObjectTypeRef `xml:"objectType"` RowType ObjectTypeRef `xml:"rowType"` } `xml:"producedTypes"` - Name string `xml:"name"` - Synonym ValueTypeRef `xml:"synonym"` - ToolTip ValueTypeRef `xml:"toolTip"` + Name string `xml:"name"` + Synonym ObjectKeyValueType `xml:"synonym"` + ToolTip ObjectKeyValueType `xml:"toolTip"` StandardAttributes struct { DataHistory string `xml:"dataHistory"` Name string `xml:"name"` @@ -112,9 +112,9 @@ type Catalog struct { } `xml:"maxValue"` } `xml:"standardAttributes"` Attributes []struct { - Uuid string `xml:"uuid,attr"` - Name string `xml:"name"` - Synonym ValueTypeRef `xml:"synonym"` + Uuid string `xml:"uuid,attr"` + Name string `xml:"name"` + Synonym ObjectKeyValueType `xml:"synonym"` Type struct { Types string `xml:"types"` DateQualifiers string `xml:"dateQualifiers"` @@ -122,7 +122,7 @@ type Catalog struct { Length string `xml:"length"` } `xml:"stringQualifiers"` } `xml:"type"` - ToolTip ValueTypeRef `xml:"toolTip"` + ToolTip ObjectKeyValueType `xml:"toolTip"` MinValue struct { Type string `xml:"type,attr"` } `xml:"minValue"` diff --git a/configuration.go b/configuration.go index 09843f68..d9b1f653 100644 --- a/configuration.go +++ b/configuration.go @@ -22,10 +22,7 @@ type Configuration struct { Mdclass xml.Attr `xml:"mdclass,attr"` Uuid string `xml:"uuid,attr"` Name string `xml:"name"` - Synonym struct { - Key string `xml:"key"` - Value string `xml:"value"` - } `xml:"synonym"` + Synonym ObjectKeyValueType `xml:"synonym"` ContainedObjects []struct { ClassId string `xml:"classId,attr,allowempty"` ObjectId string `xml:"objectId,attr,allowempty"` @@ -51,39 +48,24 @@ type Configuration struct { Use string `xml:"use"` } `xml:"functionality"` } `xml:"usedMobileApplicationFunctionalities"` - MainSectionPicture string `xml:"mainSectionPicture,allowempty"` - DefaultLanguage string `xml:"defaultLanguage"` - BriefInformation struct { - Key string `xml:"key"` - Value string `xml:"value"` - } `xml:"briefInformation"` - DetailedInformation struct { - Key string `xml:"key"` - Value string `xml:"value"` - } `xml:"detailedInformation"` - Splash string `xml:"splash,omitempty"` - Copyright struct { - Key string `xml:"key"` - Value string `xml:"value"` - } `xml:"copyright"` - VendorInformationAddress struct { - Key string `xml:"key"` - Value string `xml:"value"` - } `xml:"vendorInformationAddress"` - ConfigurationInformationAddress ValueTypeRef `xml:"configurationInformationAddress,omitempty"` - DataLockControlMode string `xml:"dataLockControlMode"` - ObjectAutonumerationMode string `xml:"objectAutonumerationMode"` - ModalityUseMode string `xml:"modalityUseMode"` - InterfaceCompatibilityMode string `xml:"interfaceCompatibilityMode"` - CompatibilityMode string `xml:"compatibilityMode"` + MainSectionPicture string `xml:"mainSectionPicture,allowempty"` + DefaultLanguage string `xml:"defaultLanguage"` + BriefInformation ObjectKeyValueType `xml:"briefInformation"` + DetailedInformation ObjectKeyValueType `xml:"detailedInformation"` + Splash string `xml:"splash,omitempty"` + Copyright ObjectKeyValueType `xml:"copyright"` + VendorInformationAddress ObjectKeyValueType `xml:"vendorInformationAddress"` + ConfigurationInformationAddress ObjectKeyValueType `xml:"configurationInformationAddress,omitempty"` + DataLockControlMode string `xml:"dataLockControlMode"` + ObjectAutonumerationMode string `xml:"objectAutonumerationMode"` + ModalityUseMode string `xml:"modalityUseMode"` + InterfaceCompatibilityMode string `xml:"interfaceCompatibilityMode"` + CompatibilityMode string `xml:"compatibilityMode"` Languages struct { - Uuid string `xml:"uuid,attr"` - Name string `xml:"name"` - Synonym struct { - Key string `xml:"key"` - Value string `xml:"value"` - } `xml:"synonym"` - LanguageCode string `xml:"languageCode"` + Uuid string `xml:"uuid,attr"` + Name string `xml:"name"` + Synonym ObjectKeyValueType `xml:"synonym"` + LanguageCode string `xml:"languageCode"` } `xml:"languages"` Subsystems []Subsystem `xml:"-"` diff --git a/encoding/xml/marshal.go b/encoding/xml/marshal.go index 2e4bc360..46139eea 100644 --- a/encoding/xml/marshal.go +++ b/encoding/xml/marshal.go @@ -401,10 +401,16 @@ func (p *printer) popPrefix() { } } +type Nullable interface { + IsNull() bool +} + var ( marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem() textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + nullableType = reflect.TypeOf((*Nullable)(nil)).Elem() + ) // marshalValue writes one or more XML elements representing val. @@ -1084,6 +1090,10 @@ func isEmptyValue(v reflect.Value) bool { return v.Uint() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 + case reflect.Struct: + if v.CanInterface() && v.Type().Implements(nullableType) { + return v.Interface().(Nullable).IsNull() + } case reflect.Interface, reflect.Ptr: return v.IsNil() } diff --git a/mdclasses_test.go b/mdclasses_test.go index 66151a16..c9395528 100644 --- a/mdclasses_test.go +++ b/mdclasses_test.go @@ -1,6 +1,8 @@ package mdclasses import ( + "github.com/v8platform/mdclasses/encoding/xml" + "os" "reflect" "testing" ) @@ -35,3 +37,43 @@ func TestUnpackConfiguration(t *testing.T) { }) } } + + + +func Test(t *testing.T) { + tests := []struct { + name string + dir string + want Configuration + wantErr bool + }{ + { + "simple", + "./tests/metadata/edt/src", + Configuration{}, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := UnpackConfiguration(tt.dir) + if (err != nil) != tt.wantErr { + t.Errorf("UnpackConfiguration() error = %v, wantErr %v", err, tt.wantErr) + return + } + xmlFile, err := os.Create("./tests/metadata/edt/src/Configuration/Configuration.mdo") + if err != nil { + t.Fatalf("Ошибка тестирования %v", got) + return + } + xmlFile.WriteString(xml.Header) + encoder := xml.NewEncoder(xmlFile) + encoder.Indent("", " ") + err = encoder.Encode(&got) + if err != nil { + t.Fatalf("Ошибка тестирования %v", got) + return + } + }) + } +} diff --git a/refType.go b/refType.go index eb42c313..768eee07 100644 --- a/refType.go +++ b/refType.go @@ -5,7 +5,11 @@ type ObjectTypeRef struct { ValueTypeId string `xml:"valueTypeId,attr"` } -type ValueTypeRef struct { - Key string `xml:"key,,omitempty"` +type ObjectKeyValueType struct { + Key string `xml:"key,omitempty"` Value string `xml:"value,omitempty"` } + +func (v ObjectKeyValueType) IsNull() bool { + return len(v.Key) == 0 && len(v.Value) == 0 +} diff --git a/subsystem.go b/subsystem.go index 73625e19..e4f26ae5 100644 --- a/subsystem.go +++ b/subsystem.go @@ -1,7 +1,7 @@ package mdclasses import ( - "encoding/xml" + "github.com/v8platform/mdclasses/encoding/xml" "strings" )