第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何從 XML 字符串中刪除 XML 意圖。?

如何從 XML 字符串中刪除 XML 意圖。?

Go
森林海 2022-06-27 10:51:44
我有一個 XML 字符串。我無法從 XML 字符串中刪除縮進(jìn)空間。我更換了換行符。  <person id="13">      <name>          <first>John</first>          <last>Doe</last>      </name>      <age>42</age>      <Married>false</Married>      <City>Hanga Roa</City>      <State>Easter Island</State>      <!-- Need more details. -->  </person>如何從 GOLANG 中的字符串中刪除 XML 縮進(jìn)空格?我希望這個 XML 像字符串一樣,<person id="13"><name><first>John</first><last>Doe</last></name><age>42</age><Married>false</Married><City>Hanga Roa</City><State>Easter Island</State><!-- Need more details. --></person>如何在 GOLANG 中做到這一點(diǎn)?
查看完整描述

3 回答

?
Smart貓小萌

TA貢獻(xiàn)1911條經(jīng)驗(yàn) 獲得超7個贊

一些背景

不幸的是,XML 不是一種正則語言,因此您根本無法使用正則表達(dá)式可靠地處理它——無論您能想出多么復(fù)雜的正則表達(dá)式。


我會從這個問題的精彩幽默開始,然后閱讀,比如說,這個。


為了演示,對您的示例進(jìn)行一個簡單的更改會破壞您的處理,例如,這可能是:


  <person id="13">

      <name>

          <first>John</first>

          <last>Doe</last>

      </name>

      <age>42</age>

      <Married>false</Married>

      <City><![CDATA[Hanga <<Roa>>]]></City>

      <State>Easter Island</State>

      <!-- Need more details. -->

  </person>

其實(shí)考慮到這個


<last>Von

Neumann</last>

為什么您認(rèn)為您可以自由地從該元素的內(nèi)容中刪除換行符?


當(dāng)然,你會說一個人不能明智地在他們的姓氏中使用換行符。

好的,但是這個呢?


<poem author="Chauser">

  <strophe number="1">  The lyf so short,

  the craft so long to lerne.</strophe>

</poem>

您不能明智地刪除該句子的兩個部分之間的空格 - 因?yàn)檫@是作者的意圖。

好吧,完整的故事在 XML 規(guī)范的“空白處理”部分中定義。
外行人嘗試在 XML 中描述空白處理如下:

  • XML 規(guī)范本身并沒有為空白指定任何特殊含義:關(guān)于空白在XML 文檔的特定位置中的含義的決定取決于該文檔的處理器。

    通過擴(kuò)展,該規(guī)范不強(qiáng)制任何“標(biāo)簽”(那些<foo></bar><quux/>事物 - 出現(xiàn)在允許 XML 標(biāo)記的點(diǎn))之間的空白是否重要:只有您自己決定。
    為了更好地理解其原因,請考慮以下文檔:

    <p>?Some text which contains an?<em>emphasized block</em>which is followed by a linebreak and more text.</p>

    這是一個完全有效的 XML,出于顯示目的,我已將標(biāo)記之后和<p>標(biāo)記之前的空格字符替換<em>為 Unicode“打開框”字符。

    請注意,整個文本?Some text which contains an?出現(xiàn)在兩個標(biāo)簽之間,并且包含明顯重要的前導(dǎo)和尾隨空格- 如果不是,則強(qiáng)調(diào)的文本(用 標(biāo)記的文本<em>…</em>將與前面的文本粘合在一起)。

    </em>相同的邏輯適用于標(biāo)簽后的換行符和更多文本。

  • XML 規(guī)范暗示將“無關(guān)緊要”的空白定義為表示一對相鄰標(biāo)簽之間的任何空白可能很方便,這些標(biāo)簽不定義單個元素。

XML 還有兩個使處理更加復(fù)雜的特征:

  • 字符實(shí)體(那些&amp;&lt;事物)允許直接插入任何 Unicode 代碼點(diǎn):例如,&#x000d;將插入換行符。

  • XML 支持特殊的“CDATA 部分”,您的解析器表面上對此一無所知。

解決方法

在我們嘗試提出解決方案之前,我們將定義我們打算將哪些空白視為無關(guān)緊要并丟棄。

看起來像您的文檔類型,定義應(yīng)該是:任何兩個標(biāo)簽之間的任何字符數(shù)據(jù)都應(yīng)該被刪除,除非:

  • 它至少包含一個非空白字符,或

  • 它完全定義了單個 XML 元素的內(nèi)容。

考慮到這些考慮,我們可以編寫代碼,將輸入 XML 流解析為令牌并將它們寫入輸出 XML 流,同時(shí)應(yīng)用以下邏輯來處理令牌:

  1. 如果它看到除字符數(shù)據(jù)之外的任何 XML 元素,它會將它們編碼到輸出流中。

    此外,如果該元素是一個開始標(biāo)簽,它會通過設(shè)置一些標(biāo)志來記住這一事實(shí);否則標(biāo)志被清除。

  2. 如果它看到任何字符數(shù)據(jù),它會檢查該字符數(shù)據(jù)是否緊跟在開始元素(開始標(biāo)記)之后,如果是,則保存該字符數(shù)據(jù)塊。

    當(dāng)已經(jīng)存在這樣的已保存塊時(shí),也會保存字符數(shù)據(jù)塊——這是必需的,因?yàn)樵?XML 中,文檔中可能有幾個相鄰但仍然不同的字符數(shù)據(jù)塊。

  3. 如果它看到任何 XML 元素,并檢測到它有一個或多個保存的字符塊,那么它首先決定是否將它們放入輸出流:

    • 如果元素是結(jié)束元素(結(jié)束標(biāo)記),則所有字符數(shù)據(jù)塊都必須“按原樣”放入輸出流中——因?yàn)樗鼈兺耆x了單個元素的內(nèi)容。

    • 否則,如果至少一個已保存的字符數(shù)據(jù)塊包含至少一個非空白字符,則所有塊都按原樣寫入輸出流。

    • 否則將跳過所有塊。

這是實(shí)現(xiàn)所描述方法的工作代碼:

package main


import (

    "encoding/xml"

    "errors"

    "fmt"

    "io"

    "os"

    "strings"

)


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

  <person id="13">

      weird text

      <name>

          <first>John</first>

          <last><![CDATA[Johnson & ]]><![CDATA[ <<Johnson>> ]]><![CDATA[ & Doe ]]></last>

      </name>&#x000d;&#x0020;&#x000a;&#x0009;<age>

      42

      </age>

      <Married>false</Married>

      <City><![CDATA[Hanga <Roa>]]></City>

      <State>Easter Island</State>

      <!-- Need more details. --> what?

      <foo> more <bar/> text </foo>

  </person>

`


func main() {

    stripped, err := removeWS(xmlData)

    if err != nil {

        fmt.Fprintln(os.Stderr, err)

        os.Exit(1)

    }

    fmt.Print(stripped)

}


func removeWS(s string) (string, error) {

    dec := xml.NewDecoder(strings.NewReader(s))


    var sb strings.Builder

    enc := NewSkipWSEncoder(&sb)


    for {

        tok, err := dec.Token()

        if err != nil {

            if err == io.EOF {

                break

            }

            return "", fmt.Errorf("failed to decode token: %w", err)

        }


        err = enc.EncodeToken(tok)

        if err != nil {

            return "", fmt.Errorf("failed to encode token: %w", err)

        }

    }


    err := enc.Flush()

    if err != nil {

        return "", fmt.Errorf("failed to flush encoder: %w", err)

    }


    return sb.String(), nil

}


type SkipWSEncoder struct {

    *xml.Encoder


    sawStartElement bool

    charData        []xml.CharData

}


func NewSkipWSEncoder(w io.Writer) *SkipWSEncoder {

    return &SkipWSEncoder{

        Encoder: xml.NewEncoder(w),

    }

}


func (swe *SkipWSEncoder) EncodeToken(tok xml.Token) error {

    if cd, isCData := tok.(xml.CharData); isCData {

        if len(swe.charData) > 0 || swe.sawStartElement {

            swe.charData = append(swe.charData, cd.Copy())

            return nil

        }

        if isWS(cd) {

            return nil

        }

        return swe.Encoder.EncodeToken(tok)

    }


    if len(swe.charData) > 0 {

        _, isEndElement := tok.(xml.EndElement)

        err := swe.flushSavedCharData(isEndElement)

        if err != nil {

            return err

        }

    }


    _, swe.sawStartElement = tok.(xml.StartElement)


    return swe.Encoder.EncodeToken(tok)

}


func (swe *SkipWSEncoder) Flush() error {

    if len(swe.charData) > 0 {

        return errors.New("attempt to flush encoder while having pending cdata")

    }

    return swe.Encoder.Flush()

}


func (swe *SkipWSEncoder) flushSavedCharData(mustKeep bool) error {

    if mustKeep || !allIsWS(swe.charData) {

        err := encodeCDataList(swe.Encoder, swe.charData)

        if err != nil {

            return err

        }

    }


    swe.charData = swe.charData[:0]


    return nil

}


func encodeCDataList(enc *xml.Encoder, cdataList []xml.CharData) error {

    for _, cd := range cdataList {

        err := enc.EncodeToken(cd)

        if err != nil {

            return err

        }

    }

    return nil

}


func isWS(b []byte) bool {

    for _, c := range b {

        switch c {

        case 0x20, 0x09, 0x0d, 0x0a:

            continue

        }

        return false

    }

    return true

}


func allIsWS(cdataList []xml.CharData) bool {

    for _, cd := range cdataList {

        if !isWS(cd) {

            return false

        }

    }

    return true

}

游樂場。


我不確定它是否完全涵蓋了所有可能的奇怪情況,但它應(yīng)該是一個好的開始。


查看完整回答
反對 回復(fù) 2022-06-27
?
aluckdog

TA貢獻(xiàn)1847條經(jīng)驗(yàn) 獲得超7個贊

刪除 XML 標(biāo)記之間的純空格序列

func unformatXML(xmlString string) string {

    var unformatXMLRegEx = regexp.MustCompile(`>\s+<`)

    unformatBetweenTags := unformatXMLRegEx.ReplaceAllString(xmlString, "><") // remove whitespace between XML tags

    return strings.TrimSpace(unformatBetweenTags) // remove whitespace before and after XML

}

正則表達(dá)式解釋

\s - 匹配任何空格,包括制表符、換行符、換頁符、回車符和空格


+ - 匹配一個或多個空白字符


正則表達(dá)式語法參考:https ://golang.org/pkg/regexp/syntax/


例子

package main


import (

    "fmt"

    "regexp"

    "strings"

)


func main() {

    var s = `    

<person id="13">

    <name>

        <first>John</first>

        <last>Doe</last>

    </name>

    <age>42</age>

    <Married>false</Married>

    <City>Hanga Roa</City>

    <State>Easter Island</State>

    <!-- Need more details. -->

</person>   `


    s = unformatXML(s)

    fmt.Println(fmt.Sprintf("'%s'", s)) // single quotes used to confirm no leading or trailing whitespace

}


func unformatXML(xmlString string) string {

    var unformatXMLRegEx = regexp.MustCompile(`>\s+<`)

    unformatBetweenTags := unformatXMLRegEx.ReplaceAllString(xmlString, "><") // remove whitespace between XML tags

    return strings.TrimSpace(unformatBetweenTags) // remove whitespace before and after XML

}

Go Playground 中的可運(yùn)行示例

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


查看完整回答
反對 回復(fù) 2022-06-27
?
斯蒂芬大帝

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超8個贊

首先需要從 XML 中刪除縮進(jìn),然后需要刪除換行符。


// Regex to remove indentation

m1 := regexp.MustCompile(`( *)<`)

newstr := m1.ReplaceAllString(xmlString, "<")


// Replace newline

newLineReplacer := strings.NewReplacer("\n", "", "\r\n", "")

xmlString = newLineReplacer.Replace(newstr)

在這里找到這個,https://play.golang.org/p/Orp2RyPbGP2


查看完整回答
反對 回復(fù) 2022-06-27
  • 3 回答
  • 0 關(guān)注
  • 142 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號