给定一个如下所示的 XML 文档:
<MasterXML>
<Processes>
<Params>
<ParamName>today</ParamName>
<ParamType>1</ParamType>
<ParamValue/>
</Params>
<Params>
<ParamName>today</ParamName>
<ParamType>2</ParamType>
<ParamValue/>
</Params>
<Params>
<ParamName>today</ParamName>
<ParamType>3</ParamType>
<ParamValue/>
</Params>
</Processes>
</MasterXML>
使用 beevik/etree for Go 包,当
<ParamValue/>
具有特定的特定值时,如何访问文档中 <Params>
的每个实例的 <ParamName>
,以用值填充它。
在给定的示例中,当
<ParamValue/>
持有值 today 时,我希望用 05/02/2024 填充所有 <Params>
节点中的所有 <ParamName>
节点。
此代码仅适用于包含许多实例的文档中
<Params>
节点的第一个实例,其中 <ParamName>
== today ,尽管循环似乎应该访问 <Params>
的每个实例:
for _, elem1 := range doc.FindElements(".//Processes//Params//ParamName") {
if elem1 == nil {
log.Fatal("Check XPath)
}
s := elem1.Text()
if s == "today" {
elem2 := elem1.FindElement("//ParamValue")
elem2.SetText("05/02/2024")
}
}
我该怎么做?为什么
range doc.FindElements(".//Processes//Params//ParamName")
找不到 <Params>
的每个实例?我应该使用不同的方法吗?
您当前的代码确实按照您所描述的方式运行,因为通过在 XPath 中使用双斜杠,您始终以递归方式搜索 XML 树,这意味着您始终从顶部找到第一个出现的位置。
这是固定样本:
package main
import (
"log"
"os"
"strings"
"github.com/beevik/etree"
)
func main() {
doc := etree.NewDocument()
if err := doc.ReadFromFile("master.xml"); err != nil {
panic(err)
}
for _, elem1 := range doc.FindElements(".//Processes//Params//ParamName") {
if elem1 == nil {
log.Fatal("Check XPath")
}
s := elem1.Text()
//println(s)
if strings.TrimSpace(s) == "today" {
elem2 := elem1.FindElement("../ParamValue")
elem2.SetText("05/02/2024")
}
}
doc.WriteTo(os.Stdout)
}
这需要
master.xml
与您的 .go
文件位于同一目录中。我选择了这个:
<MasterXML>
<Processes>
<Params>
<ParamName> today </ParamName>
<ParamType>1</ParamType>
<ParamValue/>
</Params>
<Params>
<ParamName> tomorrow </ParamName>
<ParamType>2</ParamType>
<ParamValue/>
</Params>
<Params>
<ParamName> today </ParamName>
<ParamType>3</ParamType>
<ParamValue/>
</Params>
</Processes>
</MasterXML>
产生所需的输出:
<MasterXML>
<Processes>
<Params>
<ParamName> today </ParamName>
<ParamType>1</ParamType>
<ParamValue>05/02/2024</ParamValue>
</Params>
<Params>
<ParamName> tomorrow </ParamName>
<ParamType>2</ParamType>
<ParamValue/>
</Params>
<Params>
<ParamName> today </ParamName>
<ParamType>3</ParamType>
<ParamValue>05/02/2024</ParamValue>
</Params>
</Processes>
</MasterXML>