草庐IT

xml - 如何用Go to struct list格式化这个xml?这个xml标签名是一样的,只是id不同

coder 2024-07-08 原文

我有一个 xml 代码,我想将 xml 格式化为结构列表。 我尝试使用“encoding/xml”,但 api 不支持通过标签内的 ID 进行过滤。 我想格式化 unionBankNo 和 bankName,但是错误。 请告诉我有更好的解决方案吗?

这是我的xml

<?xml version="1.0" encoding="utf-8"?>

<kColl id="noSessionSrvData" append="false"> 
  <field id="EMPException"/>  
  <field id="errorMessage"/>  
  <field id="customerId"/>  
  <field id="provinceCode"/>  
  <field id="provinceName"/>  
  <field id="cityCode" value="1000"/>  
  <field id="bankName"/>  
  <field id="bankType" value="104"/>  
  <field id="configName"/>  
  <field id="electricNo"/>  
  <field id="orderFlowNo"/>  
  <field id="dateTime"/>  
  <iColl id="iCityInfo" append="false"></iColl>  
  <iColl id="iBankInfo" append="false"> 
    <kColl id="null" append="false"> 
      <field id="unionBankNo" value="104100006610"/>  
      <field id="bankName" value="中国银行股份有限公司北京百子湾支行"/> 
    </kColl>  
    <kColl id="null" append="false"> 
      <field id="unionBankNo" value="104100004013"/>  
      <field id="bankName" value="中国银行股份有限公司北京市分行"/> 
    </kColl>  
    <kColl id="null" append="false"> 
      <field id="unionBankNo" value="104100004048"/>  
      <field id="bankName" value="中国银行股份有限公司北京崇文门支行"/> 
    </kColl>  
  </iColl>  
  <iColl id="iPayUseList" append="false"></iColl>  
  <iColl id="iBankNotice" append="false"></iColl>  
  <iColl id="iOrderList" append="false"></iColl>  
  <field id="activateCode"/>  
  <field id="payAccountOpenNode"/>  
  <iColl id="iCityBank" append="false"></iColl>  
  <field id="transferTowardType"/>  
  <field id="errorCode"/>  
  <field id="chargeFee"/>  
  <field id="userAlias"/>  
  <field id="password"/>  
  <field id="passwordEncrypted"/>  
  <field id="oldPassword"/>  
  <field id="passwordOld"/>  
  <field id="passwordNew"/>  
  <field id="userid"/>  
  <field id="flowId"/>  
  <field id="uifAlias"/>  
  <field id="stt"/>  
  <field id="queryNumber"/>  
  <field id="flagNo"/>  
  <field id="userId"/>  
  <field id="openDate"/>  
  <field id="turnPageBeginPos" value="1"/>  
  <field id="turnPageShowNum" value="10"/>  
  <field id="turnPageTotalNum"/>  
  <field id="queryType"/>  
  <field id="PBA_ID"/>  
  <field id="PBA_TYPE "/>  
  <field id="PBA_TITLE "/>  
  <field id="PBA_CONTENT "/>  
  <field id="PBA_TELLERNO "/>  
  <field id="PBA_DATETIME "/>  
  <field id="PBA_ACTIVEDATE "/>  
  <field id="PBA_EXPIREDATE "/>  
  <field id="PBA_STT "/>  
  <iColl id="iANNOUNCE" append="false"></iColl>  
  <iColl id="iUnionBankList" append="false"></iColl>  
  <field id="abateDate"/>  
  <field id="Dueday"/>  
  <field id="_ServletRequest" value=""/>  
  <field id="retValue" value="0"/> 
</kColl>

这是我的结构

type UnionInfo struct {
    UnionNo string `xml:"field>[@id='unionBankNo']>id,attr"`
    BankName string `xml:"field>[@id='bankName']>id,attr"`
}

type Result struct {
    XMLName xml.Name `xml:"kColl"`
    Name    string
    City   string    `xml:"field>[@id='cityCode']>value,attr"`
    Province string
    UnionInfo []UnionInfo `xml:"iColl/kColl"`
}
err = xml.Unmarshal([]byte(body), &v)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }

    fmt.Println(string(body))
    fmt.Println(v)

错误:xml: 字段>[@id='cityCode']>值(value)链对 attr flagExiting 无效。

最佳答案

使用 encoding/xml,您可以首先将 xml 解析为正确的 结构,然后自己过滤必要的内容。我不知道是否有第 3 方包可以使这个更简单......

type KColl struct {
    Id     string  `xml:"id,attr"`
    Append bool    `xml:"append,attr"`
    Fields []Field `xml:"field"`
    IColls []IColl `xml:"iColl"`
}

type IColl struct {
    Id     string  `xml:"id,attr"`
    Append bool    `xml:"append,attr"`
    KColls []KColl `xml:"kColl"`
}

type Field struct {
    Id    string `xml:"id,attr"`
    Value string `xml:"value,attr"`
}

func main() {
    var k KColl
    if err := xml.Unmarshal(data, &k); err != nil {
        panic(err)
    }

    var res Result
    for _, f := range k.Fields {
        if f.Id != "cityCode" {
            continue
        }
        res.City = f.Value
        break
    }
    for _, i := range k.IColls {
        if i.Id != "iBankInfo" {
            continue
        }

        for _, j := range i.KColls {
            var info UnionInfo
            for _, f := range j.Fields {
                if f.Id == "unionBankNo" {
                    info.UnionNo = f.Value
                }
                if f.Id == "bankName" {
                    info.BankName = f.Value
                }
            }
            res.UnionInfo = append(res.UnionInfo, info)

        }
    }
    fmt.Printf("%+v\n", res)
}

https://play.golang.org/p/W4LnMLKVa8z

关于xml - 如何用Go to struct list格式化这个xml?这个xml标签名是一样的,只是id不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57736582/

有关xml - 如何用Go to struct list格式化这个xml?这个xml标签名是一样的,只是id不同的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  3. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

    我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

  4. ruby-on-rails - 如何正确格式化字符串,如 'mccdougal' 到 'McDougal' - 2

    什么Ruby或RailsDSL会将字符串"mccdougal"格式化为"McDougal",同时留下字符串"McDougal"原样?将titleize传递给"McDougal"结果如下:"McDougal".titleize#=>"McDougal" 最佳答案 据我所知,没有可以处理这种情况的Rails助手。这是一个非标准的边缘案例,需要特殊处理。但是,您可以创建自定义字符串变形。您可以将这段代码放入初始化程序中:ActiveSupport::Inflector.inflections(:en)do|inflect|inflect.

  5. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  6. ruby - 这个 ruby​​ 注入(inject)魔术是如何工作的? - 2

    我今天看到了一个ruby​​代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem

  7. ruby - Rails -- :id attribute? 所需的数据库索引 - 2

    因此,当我遵循MichaelHartl的RubyonRails教程时,我注意到在用户表中,我们为:email属性添加了一个唯一索引,以提高find的效率方法,因此它不会逐行搜索。到目前为止,我们一直在根据情况使用find_by_email和find_by_id进行搜索。然而,我们从未为:id属性设置索引。:id是否自动索引,因为它在默认情况下是唯一的并且本质上是顺序的?或者情况并非如此,我应该为:id搜索添加索引吗? 最佳答案 大多数数据库(包括sqlite,这是RoR中的默认数据库)会自动索引主键,对于RailsMigration

  8. ruby-on-rails - 如何用不同的用户运行nginx主进程 - 2

    A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(

  9. ruby - 从 sinatra 中的 before do block 返回不同的值 - 2

    有没有办法在sinatra的beforedoblock中停止执行并返回不同的值?beforedo#codeishere#Iwouldliketo'return"Message"'#Iwouldlike"/home"tonotgetcalled.end//restofthecodeget'/home'doend 最佳答案 beforedohalt401,{'Content-Type'=>'text/plain'},'Message!'end如果你愿意,你可以只指定状态,这里有状态、标题和正文的例子

  10. ruby-on-rails - Sunspot:如何对具有不同值的多个字段进行全文查询? - 2

    我想用sunspot重现以下原始solr查询q=exact_term_text:fooORterm_textv:foo*ORalternate_text:bar*但我无法通过标准的太阳黑子界面理解这是否可能以及如何实现,因为看起来:fulltext方法似乎不接受多个文本/搜索字段参数我不知道将什么参数作为第一个参数传递给fulltext,就好像我通过了"foo"或"bar"结果不匹配如果我传递一个空参数,我得到一个q=*:*范围过滤器(例如with(:term).starting_with('foo*')(顾名思义)作为过滤器查询应用,因此不参与评分。似乎可以手动编写字符串(或者可能使

随机推荐