在两个名称空间中解组具有相同属性名称的XML属性

在两个名称空间中解组具有相同属性名称的XML属性,xml,go,Xml,Go,我有一个XML结构,其中有一个未命名的“type”属性和一个命名的属性。我无法让GO的解组器同时读取两个“类型”属性 XML是: data := `<response xmlns="urn:debugger_protocol_v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <map name="bool" type="bool_T" xsi:type="xsd:boolean"></map>

我有一个XML结构,其中有一个未命名的“type”属性和一个命名的属性。我无法让GO的解组器同时读取两个“类型”属性

XML是:

data := `<response xmlns="urn:debugger_protocol_v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<map name="bool" type="bool_T" xsi:type="xsd:boolean"></map>
<map name="int" type="int_T" xsi:type="xsd:decimal"></map>
</response>`
运行以下代码时:

package main

import (
    "encoding/xml"
    "fmt"
    "strings"
)

type Typemap struct {
    XMLName xml.Name `xml:"map"`
    Name    string   `xml:"name,attr"`
    Type    string   `xml:"urn:debugger_protocol_v1 type,attr"`
    XsiType string   `xml:"http://www.w3.org/2001/XMLSchema-instance type,attr"`
}

type Response struct {
    XMLName xml.Name  `xml:"response"`
    Typemap []Typemap `xml:"map,omitempty"`
}

func main() {
    rq := new(Response)
    data := `<response xmlns="urn:debugger_protocol_v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<map name="bool" type="bool_T" xsi:type="xsd:boolean"></map>
<map name="int" type="int_T" xsi:type="xsd:decimal"></map>
</response>`

    reader := strings.NewReader(data)

    decoder := xml.NewDecoder(reader)

    err := decoder.Decode(&rq)

    if err != nil {
        fmt.Println(err)
    }

    fmt.Printf("Unmarshalled Content:\n%v", rq)
}

如果从定义中删除
urn:debugger\u protocol\u v1
,则会出现以下错误:

main.Typemap field "Type" with tag "type,attr" conflicts with field "XsiType" with tag "http://www.w3.org/2001/XMLSchema-instance type,attr"
我无法更改原始XML数据格式。是否有方法将两个
类型
属性都解组


我也设置了围棋

事实证明,目前没有办法在围棋中本机实现这一点。有一个列表,以及一个描述它的描述,但这还没有得到解决

然而,我也找到了一个解决办法。您可以编写自己的解组代码,既可以用于,也可以用于

对于属性,可以实现如下内容:

type NonMarshalled string

func (s *NonMarshalled) UnmarshalXMLAttr(attr xml.Attr) error {
    fmt.Printf("Parsing attribute '%s', with value '%s'", attr.Name.Local, attr.Value)
    s.Title = strings.ToUpper(attr.Value)
    return nil
}

type Typemap struct {
    XMLName xml.Name `xml:"map"`
    Name    string   `xml:"name,attr"`
    Type    NonNamespaced `xml:"type,attr"`
    XsiType string   `xml:"http://www.w3.org/2001/XMLSchema-instance type,attr"`
}
但是,这不可能同时具有名称空间属性名和具有相同名称的非名称空间属性名。这仍然会导致:

main.Typemap field "Type" with tag "type,attr" conflicts with field "XsiType" with tag "http://www.w3.org/2001/XMLSchema-instance type,attr"
这里的解决方法是为整个
Typemap
类型编写一个解组器。在我的例子中,此代码如下所示:

func (s *Typemap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {                                         
    nameAttr := ""                                                                                                     
    typeAttr := ""                                                                                                     
    xsiTypeAttr := ""                                                                                                  

    for _, attr := range start.Attr {                                                                                  
        if attr.Name.Space == "" && attr.Name.Local == "name" {                                                        
            nameAttr = attr.Value                                                                                      
        }                                                                                                              
        if attr.Name.Space == "" && attr.Name.Local == "type" {                                                        
            typeAttr = attr.Value                                                                                      
        }                                                                                                              
        if attr.Name.Space == "http://www.w3.org/2001/XMLSchema-instance" && attr.Name.Local == "type" {               
            xsiTypeAttr = attr.Value                                                                                   
        }                                                                                                              
    }                                                                                                                  

    d.Skip()                                                                                                           
    *s = Typemap{Name: nameAttr, Type: typeAttr, XsiType: xsiTypeAttr}                                                 

    return nil                                                                                                         
}                                                                                                                      

我对围棋不太熟悉,但我试过你的游乐场,这显然是图书馆设计师的疏忽。顺便说一下,那些
类型
属性的实际名称空间是空名称空间,而不是
urn:debugger\u protocol\u v1
。一个想法是,可以通过XSLT运行XML,将
类型
属性重命名为其他属性,然后解析转换后的XML。这有点迂回,但我认为应该行得通。这很可能是疏忽。我还没有完全意识到它是空名称空间。。。但我确实尝试过使用
\uu
而不是URN,正如编组步骤所示,但这会产生错误,我不知道如何指定它。如果没有“正确”的解析方法,我可能不采用XSLT方法,而只进行字符串替换。
main.Typemap field "Type" with tag "type,attr" conflicts with field "XsiType" with tag "http://www.w3.org/2001/XMLSchema-instance type,attr"
func (s *Typemap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {                                         
    nameAttr := ""                                                                                                     
    typeAttr := ""                                                                                                     
    xsiTypeAttr := ""                                                                                                  

    for _, attr := range start.Attr {                                                                                  
        if attr.Name.Space == "" && attr.Name.Local == "name" {                                                        
            nameAttr = attr.Value                                                                                      
        }                                                                                                              
        if attr.Name.Space == "" && attr.Name.Local == "type" {                                                        
            typeAttr = attr.Value                                                                                      
        }                                                                                                              
        if attr.Name.Space == "http://www.w3.org/2001/XMLSchema-instance" && attr.Name.Local == "type" {               
            xsiTypeAttr = attr.Value                                                                                   
        }                                                                                                              
    }                                                                                                                  

    d.Skip()                                                                                                           
    *s = Typemap{Name: nameAttr, Type: typeAttr, XsiType: xsiTypeAttr}                                                 

    return nil                                                                                                         
}