首页 > 解决方案 > 按属性读取 XML

问题描述

尝试使用 Golang 连接到 MS 共享点,如此所述,因此我编写了以下返回 XML 文本的内容:

package main

import (
    "bytes"
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "strings"
)

func main() {
    const myurl = "https://login.microsoftonline.com/extSTS.srf"
    const username = "myuser@mydmain.com"
    const password = "mypassword"
    const endpoint = "https://mydomain.sharepoint.com/"
    const xmlbody = `
    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
    xmlns:a="http://www.w3.org/2005/08/addressing"
    xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
  <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
  <a:ReplyTo>
    <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
  </a:ReplyTo>
  <a:To s:mustUnderstand="1">https://login.microsoftonline.com/extSTS.srf</a:To>
  <o:Security s:mustUnderstand="1"
     xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <o:UsernameToken>
      <o:Username>` + username + `</o:Username>
      <o:Password>` + password + `</o:Password>
    </o:UsernameToken>
  </o:Security>
</s:Header>
<s:Body>
  <t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
    <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
      <a:EndpointReference>
        <a:Address>` + endpoint + `</a:Address>
      </a:EndpointReference>
    </wsp:AppliesTo>
    <t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
    <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
    <t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType>
  </t:RequestSecurityToken>
</s:Body>
</s:Envelope>`

    resp, err := http.Post(myurl, "text/xml", strings.NewReader(xmlbody))
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println("response Body:", string(body))
}

以上能够完美地完成第一步,现在我想获取返回的字符串并读取具有的xml元素ID="Compact0",所以我尝试了这个:

type Node struct {
    XMLName xml.Name
    Attrs   []xml.Attr `xml:"-"`
    Content []byte     `xml:",innerxml"`
    Nodes   []Node     `xml:",any"`
}

func walk(nodes []Node, f func(Node) bool) {
    for _, n := range nodes {
        if f(n) {
            walk(n.Nodes, f)
        }
    }
}

func main() {
    // My code above, followed by:
    var n Node
    var data = []byte(body)
    buf := bytes.NewBuffer(data)
    dec := xml.NewDecoder(buf)
    err = dec.Decode(&n)
    if err != nil {
        panic(err)
    }
    walk([]Node{n}, func(n Node) bool {
        if n.Attrs == "Compact0" {.  // <= ERROR
            fmt.Println(string(n.Content))
        }
        return true
    })
}

但我得到了这个错误:

无法将“Compact0”(无类型字符串常量)转换为 []xml.AttrcompilerInvalidUntypedConversion

在:

如果 n.Attrs == "Compact0" {}

返回的XML响应是:

<?xml version="1.0" encoding="utf-8"?>
<S:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing" 
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" 
xmlns:S="http://www.w3.org/2003/05/soap-envelope">
    <S:Header>
        <wsa:Action S:mustUnderstand="1" wsu:Id="Action">http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue</wsa:Action>
        <wsa:To S:mustUnderstand="1" wsu:Id="To">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
        <wsse:Security S:mustUnderstand="1">
            <wsu:Timestamp wsu:Id="TS" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsu:Created>2021-06-30T18:38:50.5911765Z</wsu:Created>
            <wsu:Expires>2021-06-30T18:43:50.5911765Z</wsu:Expires>
            </wsu:Timestamp>
        </wsse:Security>
    </S:Header>
    <S:Body xmlns:S="http://www.w3.org/2003/05/soap-envelope">
        <wst:RequestSecurityTokenResponse xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" x
        mlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
        xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">
            <wst:TokenType>urn:passport:compact</wst:TokenType>
            <wsp:AppliesTo>
                <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
                    <wsa:Address>https://mydomain.sharepoint.com/</wsa:Address>
                </wsa:EndpointReference>
            </wsp:AppliesTo>
            <wst:Lifetime>
                <wsu:Created>2021-06-30T18:38:49Z</wsu:Created>
                <wsu:Expires>2021-07-01T18:38:49Z</wsu:Expires>
            </wst:Lifetime>
            <wst:RequestedSecurityToken>
                <wsse:BinarySecurityToken Id="Compact0" 
                xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                t=blablabla==&amp;p=
                </wsse:BinarySecurityToken>
            </wst:RequestedSecurityToken>
            <wst:RequestedAttachedReference>
                <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                    <wsse:Reference URI="VkETyJDRdMqocUhjsNftrfT9Z8U="></wsse:Reference>
                </wsse:SecurityTokenReference>
            </wst:RequestedAttachedReference>
            <wst:RequestedUnattachedReference>
                <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                    <wsse:Reference URI="VkETyJDRdMqocUhjsNftrfT9Z8U="></wsse:Reference>
                </wsse:SecurityTokenReference>
            </wst:RequestedUnattachedReference>
        </wst:RequestSecurityTokenResponse>
    </S:Body>
</S:Envelope>

我需要从中获取blablabla

                <wsse:BinarySecurityToken Id="Compact0" 
                xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                t=blablabla==&amp;p=
                </wsse:BinarySecurityToken>

标签: go

解决方案


和:

    Attrs   []xml.Attr `xml:"-"`

您忽略了所有属性。你应该能够做到:

   ID string `xml:"Id,attr"

而是检查您要查找的 ID。

您收到该错误是因为n.Attrs它是一个数组。您不能将数组与字符串值进行比较。


推荐阅读