英文:
How to get xml prefix in golang in dynamic xml without struct
问题
假设我有这样的XML:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.opentravel.org/OTA/2003/05">
<soap:Header/>
<soap:Body>
<contents>
<article>
<category>Server</category>
<title>Connect to Oracle Server using Golang and Go-OCI8 on Ubuntu</title>
<url>/go-oci8-oracle-linux/</url>
</article>
<!-- ... -->
</contents>
</soap:Body>
</soap:Envelope>
我还有这样的常见结构体:
type envelope struct {
XMLName xml.Name
Attrs []xml.Attr `xml:",any,attr"`
Body struct {
InnerXML []byte `xml:",innerxml"`
}
}
问题是如何获取最外层包装器中的 soap
(来自 soap:Envelope
)这个词。
英文:
Suppose I have an XML like this
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.opentravel.org/OTA/2003/05">
<soap:Header/>
<soap:Body>
<contents>
<article>
<category>Server</category>
<title>Connect to Oracle Server using Golang and Go-OCI8 on Ubuntu</title>
<url>/go-oci8-oracle-linux/</url>
</article>
<!-- ... -->
</contents>
</soap:Body>
</soap:Envelope>
I also have common struct like this
type envelope struct {
XMLName xml.Name
Attrs []xml.Attr `xml:",any,attr"`
Body struct {
InnerXML []byte `xml:",innerxml"`
}
}
The problem is how to get the word soap
(from soap:Envelope
)in the most outer wrapper
答案1
得分: 1
我不确定这个解决方案的限制,如果有的话,请在评论中指出。
- 您可以直接使用结构体来捕获根节点的前缀URI。
- 获取属性的切片,每个属性都有一个将URI映射到前缀名称的结构体。
- 遍历属性,并尝试将每个属性的值与节点的前缀URI进行匹配,然后
- 保存属性的本地名称和前缀的名称。
(我认为这一切都是有道理的,我用正确的名称调用了正确的东西)
以下是代码示例:
var e envelope
xml.Unmarshal(data, &e)
var rootURI, rootPrefix string
rootURI = e.XMLName.Space
for _, attr := range e.Attrs {
if attr.Name.Space == "xmlns" && attr.Value == rootURI {
rootPrefix = attr.Name.Local
break
}
}
fmt.Println(rootPrefix, rootURI)
当我使用您的示例XML运行该代码时,输出结果为:
soap http://schemas.xmlsoap.org/soap/envelope/
这是完整的演示,点击此处查看。
英文:
I'm not sure of the limitations of this solution; please kindly point them out in the comments.
- You can use your struct as is to capture the root node's prefix URI
- get the slice of attributes, each of which has a struct that maps a URI to a name for the prefix
- iterate the attributes and try to match each attribute's value to the node's prefix URI, then
- save the attribute's local name, the name of the prefix
(I think that all makes sense, I called the right things by the right names)
Here's what it looks like:
var e envelope
xml.Unmarshal(data, &e)
var rootURI, rootPrefix string
rootURI = e.XMLName.Space
for _, attr := range e.Attrs {
if attr.Name.Space == "xmlns" && attr.Value == rootURI {
rootPrefix = attr.Name.Local
break
}
}
fmt.Println(rootPrefix, rootURI)
When I run that with your sample XML, it prints:
soap http://schemas.xmlsoap.org/soap/envelope/
Here's the complete demo, <https://go.dev/play/p/x3FKfkCW64x>.
答案2
得分: 0
我找到了一个名为https://github.com/beevik/etree的golang库,所以我的代码将会是这样的:
func getPrefix(xmlbytes []byte) string {
doc := etree.NewDocument()
if err := doc.ReadFromBytes(xmlbytes); err != nil {
log.Fatal(err.Error())
}
return doc.Root().Space
}
英文:
I found a golang library that is called https://github.com/beevik/etree so my code will be like this
func getPrefix(xmlbytes []byte) string {
doc := etree.NewDocument()
if err := doc.ReadFromBytes(xmlbytes); err != nil {
log.Fatal(err.Error())
}
return doc.Root().Space
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论