Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.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
如何在Go中解组包含脏HTML的XML_Xml_Google App Engine_Go - Fatal编程技术网

如何在Go中解组包含脏HTML的XML

如何在Go中解组包含脏HTML的XML,xml,google-app-engine,go,Xml,Google App Engine,Go,我有一些XML我想解组,但它包含脏HTML在一个领域,我甚至不关心。我在这里发布了一个示例: 有没有办法让解码器跳过或忽略这些错误?我尝试制作文档中描述的非严格解码器,但无法获得任何AutoClose或Entity值的组合来实现此功能。我应该提到,这个XML来自我无法控制的第三方,而且内容总是可变的,我不确定编译要跳过的静态元素列表是否可行。使用xml:“-”标记将Description添加到结构中没有任何区别 我能够用Python2.7解析它,所以我希望它在Go中是可能的——尽管我更喜欢在我的

我有一些XML我想解组,但它包含脏HTML在一个领域,我甚至不关心。我在这里发布了一个示例:

有没有办法让解码器跳过或忽略这些错误?我尝试制作文档中描述的非严格解码器,但无法获得任何
AutoClose
Entity
值的组合来实现此功能。我应该提到,这个XML来自我无法控制的第三方,而且内容总是可变的,我不确定编译要跳过的静态元素列表是否可行。使用
xml:“-”
标记将
Description
添加到结构中没有任何区别

我能够用Python2.7解析它,所以我希望它在Go中是可能的——尽管我更喜欢在我的用例中使用Go:)——为此我使用Google的AppEngine,所以解决方案必须是本机Go,而不是依赖外部C库

相关代码:

var XMLData = []byte(`<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <Container>
   <Timestamp>2014-01-15T21:07:07.217Z</Timestamp>
   <Item>
    <Description>
<table  width="100%" border=0 ><tr><td><table width="100%"><tr><td><!-- Begin Description -->
<TABLE cellSpacing=27 cellPadding=0 width="100%"><TBODY><TR><TD vAlign=top><P align=center>
<TABLE cellPadding=15 width="86%" border=1><TBODY><TR><TD><H3><P>
<H2><H2><H2><H2><H2><H2><H2><H2><H2><H2><H2><H2><H><H2><H2>


<IMG SRC=http://www.REMOVED.com/simage/j6x516.jpg>
<BR><BR>
<IMG SRC=http://www.REMOVED.com/simage/j6x517.jpg>

    </Description>
   </Item>
  <Container>
 </soapenv:Body>
</soapenv:Envelope>`)

type Data struct {
    Timestamp string `xml:"Body>Container>Timestamp"`
}

var o Data
decoder := xml.NewDecoder(bytes.NewBuffer(XMLData))
decoder.Strict = false
decoder.AutoClose = xml.HTMLAutoClose
decoder.Entity = xml.HTMLEntity
if err := decoder.Decode(&o); err != nil {
    fmt.Println("Error: ", err)
} else {
    fmt.Println("Timestamp: ", o.Timestamp)
}
var XMLData=[]字节(`
2014-01-15T21:07:07.217Z



`) 类型数据结构{ 时间戳字符串`xml:“正文>容器>时间戳”` } var o数据 解码器:=xml.NewDecoder(bytes.NewBuffer(XMLData)) decoder.Strict=false decoder.AutoClose=xml.HTMLAutoClose decoder.Entity=xml.HTMLEntity if err:=解码器。解码(&o);呃!=零{ fmt.Println(“错误:”,错误) }否则{ fmt.Println(“时间戳:”,o.Timestamp) }

结果:
错误:第14行的XML语法错误:元素中应为/>


谢谢。

作为
xml
包的替代方案,如果您已经安装,您可以使用它在Go中利用其解析灵活性

例如,使用XPath进行评估:

package main

import (
    "fmt"
    "github.com/moovweb/gokogiri"
    "github.com/moovweb/gokogiri/xml"
    "github.com/moovweb/gokogiri/xpath"
)

func main() {
    var XMLData = []byte(`<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<Container>
<Timestamp>2014-01-15T21:07:07.217Z</Timestamp>
<Item>
    <Description>
<table  width="100%" border=0 ><tr><td><table width="100%"><tr><td><!-- Begin Description -->
<TABLE cellSpacing=27 cellPadding=0 width="100%"><TBODY><TR><TD vAlign=top><P align=center>
<TABLE cellPadding=15 width="86%" border=1><TBODY><TR><TD><H3><P>
<H2><H2><H2><H2><H2><H2><H2><H2><H2><H2><H2><H2><H><H2><H2>


<IMG SRC=http://www.REMOVED.com/simage/j6x516.jpg>
<BR><BR>
<IMG SRC=http://www.REMOVED.com/simage/j6x517.jpg>

    </Description>
</Item>
<Container>
</soapenv:Body>
</soapenv:Envelope>`)

    doc, err := gokogiri.ParseXml(XMLData)

    if err != nil {
        fmt.Printf("XML document could not be parsed")
        return
    }

    nxpath := xpath.NewXPath(doc.DocPtr())
    nodes, err := nxpath.Evaluate(doc.DocPtr(), xpath.Compile("//Timestamp"))

    if err != nil {
        fmt.Printf("XPath could not be evaluated")
        return
    }

    if len(nodes) == 0 {
        fmt.Printf("Elements matching XPath not found")
        return

    }
    timestamp := xml.NewNode(nodes[0], doc).InnerHtml()

    fmt.Printf("%s", timestamp) // "2014-01-15T21:07:07.217Z"
}

主程序包
进口(
“fmt”
“github.com/moovweb/gokogiri”
“github.com/moovweb/gokogiri/xml”
“github.com/moovweb/gokogiri/xpath”
)
func main(){
var XMLData=[]字节(`
2014-01-15T21:07:07.217Z



`) doc,err:=gokogiri.ParseXml(XMLData) 如果错误!=零{ Printf(“无法解析XML文档”) 返回 } nxpath:=xpath.NewXPath(doc.DocPtr()) 节点,err:=nxpath.Evaluate(doc.DocPtr(),xpath.Compile(“//时间戳”)) 如果错误!=零{ Printf(“无法计算XPath”) 返回 } 如果len(节点)==0{ Printf(“未找到匹配XPath的元素”) 返回 } 时间戳:=xml.NewNode(节点[0],doc).InnerHtml() fmt.Printf(“%s”,时间戳)/“2014-01-15T21:07:07.217Z” }

这适用于OS X 10.9.1上的Go v1.2。Gokogiri软件包还包括一个CSS选择器转换器,但我从未使用过它,也不能对此进行担保。

您的解码器代码很好(您可以实际删除
decoder.AutoClose=xml.HTMLAutoClose
行)。问题是
img
标记在
src
属性周围没有引号。请参阅。

考虑使用软件包-对我来说,它解析了您的样本数据

在我看来,这个包的问题在于它向您返回了一个“节点”(每个HTML元素一个)的层次结构,您应该遍历这些节点。我的意思是,至少在第一眼看到的时候,没有对结构进行解包。因此,您可能会更幸运地使用或之类的东西,它应该允许您使用().so().called().fluent().style()查询已解析的DOM

这是另一种可能的选择


换句话说,我的关键思想是将处理的整个SOAP回复视为HTML,不是XML,因为这才是真正的XML,希望HTML解析器能够处理它,这要感谢HTML更宽松的格式规则和更宽松的解析器。

您看过使用
XML.Decoder.decodelement
方法吗?RawToken和Skip看起来可能会派上用场。谢谢,但我在AppEngine上托管了它,我认为我无法使用libxml2,尽管这似乎在更一般的用例中解决了这个问题。很抱歉,在我的问题中没有指定平台,我现在将更新它。嗯,那么对此可以做些什么?我无法控制XML,因此无法在其源代码处“修复”草率的HTML。是否有其他XML解码器能够完成解析的原因,但Go's不能?我想其他解析器的要求不那么严格。可能的解决方案:regex搜索和替换来修复img src。或者用cdata标记包围描述标记。