Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 获取原始元素表示,包括打开和关闭标记_Xml_Go - Fatal编程技术网

Xml 获取原始元素表示,包括打开和关闭标记

Xml 获取原始元素表示,包括打开和关闭标记,xml,go,Xml,Go,我知道golang xml,innerxml标记,它允许以原始xml的形式获取元素内部内容。但我需要的是将整个元素(开放标记、内部内容、关闭标记)作为原始数据 下面是一个我想用这种方式解析的示例。我希望获得整个及其所有可能的属性元素,并避免获得无用的元素 主程序包 进口( “编码/xml” “fmt” ) 常数数据=` 废话 废话 内部字段1值 内部字段2值 内部字段3值 废话 ` func main(){ doc:=文档{} 错误:=xml.Unmarshal([]字节(数据),&doc) 如

我知道golang xml
,innerxml
标记,它允许以原始xml的形式获取元素内部内容。但我需要的是将整个元素(开放标记、内部内容、关闭标记)作为原始数据

下面是一个我想用这种方式解析的示例。我希望获得整个
及其所有可能的属性元素,并避免获得无用的元素

主程序包
进口(
“编码/xml”
“fmt”
)
常数数据=`
废话
废话
内部字段1值
内部字段2值
内部字段3值
废话
`
func main(){
doc:=文档{}
错误:=xml.Unmarshal([]字节(数据),&doc)
如果错误!=零{
恐慌(错误)
}
fmt.Println(文件有用数据)
}
类型文档结构{
XMLName xml.Name`xml:“文档”`
有用结构{
数据字符串'xml:,innerxml'`
}`xml:“有用”`
}
操场中代码的链接如下:

这就是我得到的:

    <InnerField1>Inner field 1 value</InnerField1>
    <InnerField2>Inner field 2 value</InnerField2>
    <InnerField3>Inner field 3 value</InnerField3>
内部字段1值
内部字段2值
内部字段3值
这就是我想要的:

<Useful someAttr="someVal">
    <InnerField1>Inner field 1 value</InnerField1>
    <InnerField2>Inner field 2 value</InnerField2>
    <InnerField3>Inner field 3 value</InnerField3>
</Useful>

内部字段1值
内部字段2值
内部字段3值
请注意,我使用的实际结构要复杂得多。我不希望将整个
内部内容作为原始xml,然后对其进行解析,试图手动去除无用的元素。
部分各不相同,因此我不能硬编码例如属性,因为它们在不同的文档中可能有所不同。

捕获属性也是如此 您可以在
有用的
结构中使用附加字段来捕获所有属性(类型切片的属性),如下所示:

Useful  struct {
    Attrs []xml.Attr `xml:",any,attr"`
    Data  string     `xml:",innerxml"`
} `xml:"Useful"`
dec := xml.NewDecoder(strings.NewReader(data))

var start, end int64
for {
    start = dec.InputOffset()
    t, err := dec.Token()
    if err != nil {
        if err != io.EOF {
            fmt.Println(err)
        }
        break
    }
    if se, ok := t.(xml.StartElement); ok {
        if se.Name.Local != "Useful" {
            continue
        }
        if err := dec.Skip(); err != nil {
            fmt.Println(err)
            break
        }
        end = dec.InputOffset()
        break
    }
}

fmt.Println(data[start:end])
将另一个属性添加到
时:

真正获得完整的原始XML 另一种更复杂的方法是使用令牌读取输入,并标记
的开始和结束位置。然后您可以获得
的完整原始XML

这就是它的样子:

dec := xml.NewDecoder(strings.NewReader(data))

var start, end int64
foundStart := false
for {
    if !foundStart {
        start = dec.InputOffset()
    }
    t, err := dec.Token()
    if err != nil {
        if err != io.EOF {
            fmt.Println(err)
        }
        break
    }
    if se, ok := t.(xml.StartElement); ok {
        if se.Name.Local == "Useful" {
            foundStart = true
        }
    }
    if se, ok := t.(xml.EndElement); ok {
        if se.Name.Local == "Useful" {
            end = dec.InputOffset()
            // We may break here, we got what we wanted
            break
        }
    }
}

fmt.Println(data[start:end])
它输出(在屏幕上试用):


输出是相同的。在.

上尝试此方法,另一种方法是使用unmarshaler接口@mkopriva Post it作为替代方法。
dec := xml.NewDecoder(strings.NewReader(data))

var start, end int64
foundStart := false
for {
    if !foundStart {
        start = dec.InputOffset()
    }
    t, err := dec.Token()
    if err != nil {
        if err != io.EOF {
            fmt.Println(err)
        }
        break
    }
    if se, ok := t.(xml.StartElement); ok {
        if se.Name.Local == "Useful" {
            foundStart = true
        }
    }
    if se, ok := t.(xml.EndElement); ok {
        if se.Name.Local == "Useful" {
            end = dec.InputOffset()
            // We may break here, we got what we wanted
            break
        }
    }
}

fmt.Println(data[start:end])
<Useful someAttr="someVal" someAttr2="someVal2">
        <InnerField1>Inner field 1 value</InnerField1>
        <InnerField2>Inner field 2 value</InnerField2>
        <InnerField3>Inner field 3 value</InnerField3>
    </Useful>
dec := xml.NewDecoder(strings.NewReader(data))

var start, end int64
for {
    start = dec.InputOffset()
    t, err := dec.Token()
    if err != nil {
        if err != io.EOF {
            fmt.Println(err)
        }
        break
    }
    if se, ok := t.(xml.StartElement); ok {
        if se.Name.Local != "Useful" {
            continue
        }
        if err := dec.Skip(); err != nil {
            fmt.Println(err)
            break
        }
        end = dec.InputOffset()
        break
    }
}

fmt.Println(data[start:end])