虽然 JSON 更流行,但 XML 仍然在很多场景中使用。Gin 同样支持 XML 绑定。
type User struct {
XMLName xml.Name `xml:"user"`
Name string `xml:"name"`
Email string `xml:"email"`
}
r.POST("/users", func(c *gin.Context) {
var user User
if err := c.ShouldBindXML(&user); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(200, user)
})
请求:
curl -X POST http://localhost:8080/users \
-H "Content-Type: application/xml" \
-d '<user><name>Alice</name><email>alice@example.com</email></user>'
type User struct {
XMLName xml.Name `xml:"user"`
ID int `xml:"id,attr"`
Name string `xml:"name"`
Email string `xml:"email"`
Address string `xml:"address>city"`
Comments []string `xml:"comments>comment"`
}
| 选项 | 说明 |
|---|---|
xml:"name" | 元素名 |
xml:",attr" | 属性 |
xml:",chardata" | 字符数据 |
xml:",innerxml" | 原始 XML |
xml:",comment" | 注释 |
xml:"a>b" | 嵌套路径 |
type Product struct {
XMLName xml.Name `xml:"product"`
ID string `xml:"id,attr"`
Name string `xml:"name,attr"`
Price float64 `xml:"price,attr"`
}
r.POST("/products", func(c *gin.Context) {
var product Product
if err := c.ShouldBindXML(&product); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(200, product)
})
请求:
<product id="123" name="iPhone" price="999.99">
</product>
type Order struct {
XMLName xml.Name `xml:"order"`
ID string `xml:"id"`
Customer Customer `xml:"customer"`
Items []Item `xml:"items>item"`
}
type Customer struct {
Name string `xml:"name"`
Email string `xml:"email"`
}
type Item struct {
ProductID string `xml:"product_id"`
Quantity int `xml:"quantity"`
Price float64 `xml:"price"`
}
r.POST("/orders", func(c *gin.Context) {
var order Order
if err := c.ShouldBindXML(&order); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(200, order)
})
请求:
<order>
<id>ORD-001</id>
<customer>
<name>Alice</name>
<email>alice@example.com</email>
</customer>
<items>
<item>
<product_id>P001</product_id>
<quantity>2</quantity>
<price>99.99</price>
</item>
<item>
<product_id>P002</product_id>
<quantity>1</quantity>
<price>49.99</price>
</item>
</items>
</order>
r.GET("/users/:id", func(c *gin.Context) {
user := User{
Name: "Alice",
Email: "alice@example.com",
}
c.XML(200, user)
})
package main
import (
"encoding/xml"
"github.com/gin-gonic/gin"
"net/http"
)
type User struct {
XMLName xml.Name `xml:"user"`
ID string `xml:"id,attr"`
Name string `xml:"name"`
Email string `xml:"email"`
}
type CreateUserRequest struct {
XMLName xml.Name `xml:"user"`
Name string `xml:"name" binding:"required"`
Email string `xml:"email" binding:"required,email"`
}
func main() {
r := gin.Default()
r.POST("/users", createUser)
r.GET("/users/:id", getUser)
r.Run(":8080")
}
func createUser(c *gin.Context) {
var req CreateUserRequest
if err := c.ShouldBindXML(&req); err != nil {
c.XML(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
user := User{
ID: "123",
Name: req.Name,
Email: req.Email,
}
c.XML(http.StatusCreated, user)
}
func getUser(c *gin.Context) {
id := c.Param("id")
user := User{
ID: id,
Name: "User " + id,
Email: "user@example.com",
}
c.XML(http.StatusOK, user)
}
这一章学习了: