xmlquery is Golang XPath package for XML query.

xmlquery

Build Status Coverage Status GoDoc Go Report Card

Overview

xmlquery is an XPath query package for XML documents, allowing you to extract data or evaluate from XML documents with an XPath expression.

xmlquery has a built-in query object caching feature that caches recently used XPATH query strings. Enabling caching can avoid recompile XPath expression for each query.

Change Logs

2020-08-??

  • Add XML stream loading and parsing support.

2019-11-11

  • Add XPath query caching.

2019-10-05

  • Add new methods compatible with invalid XPath expression error: QueryAll and Query.
  • Add QuerySelector and QuerySelectorAll methods, support for reused query objects.
  • PR #12 (Thanks @FrancescoIlario)
  • PR #11 (Thanks @gjvnq)

2018-12-23

  • Added XML output including comment nodes. #9

2018-12-03

  • Added support to attribute name with namespace prefix and XML output. #6

Installation

 $ go get github.com/antchfx/xmlquery

Getting Started

Find specified XPath query.

list, err := xmlquery.QueryAll(doc, "a")
if err != nil {
	panic(err)
}

Parse an XML from URL.

doc, err := xmlquery.LoadURL("http://www.example.com/sitemap.xml")

Parse an XML from string.

s := `<?xml version="1.0" encoding="utf-8"?><rss version="2.0"></rss>`
doc, err := xmlquery.Parse(strings.NewReader(s))

Parse an XML from io.Reader.

f, err := os.Open("../books.xml")
doc, err := xmlquery.Parse(f)

Parse an XML in a stream fashion (simple case without elements filtering).

f, err := os.Open("../books.xml")
p, err := xmlquery.CreateStreamParser(f, "/bookstore/book")
for {
	n, err := p.Read()
	if err == io.EOF {
		break
	}
	if err != nil {
		...
	}
}

Parse an XML in a stream fashion (simple case advanced element filtering).

f, err := os.Open("../books.xml")
p, err := xmlquery.CreateStreamParser(f, "/bookstore/book", "/bookstore/book[price>=10]")
for {
	n, err := p.Read()
	if err == io.EOF {
		break
	}
	if err != nil {
		...
	}
}

Find authors of all books in the bookstore.

list := xmlquery.Find(doc, "//book//author")
// or
list := xmlquery.Find(doc, "//author")

Find the second book.

book := xmlquery.FindOne(doc, "//book[2]")

Find all book elements and only get id attribute. (New Feature)

list := xmlquery.Find(doc,"//book/@id")

Find all books with id bk104.

list := xmlquery.Find(doc, "//book[@id='bk104']")

Find all books with price less than 5.

list := xmlquery.Find(doc, "//book[price<5]")

Evaluate total price of all books.

expr, err := xpath.Compile("sum(//book/price)")
price := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64)
fmt.Printf("total price: %f\n", price)

Evaluate number of all book elements.

expr, err := xpath.Compile("count(//book)")
price := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64)

FAQ

Find() vs QueryAll(), which is better?

Find and QueryAll both do the same thing: searches all of matched XML nodes. Find panics if provided with an invalid XPath query, while QueryAll returns an error.

Can I save my query expression object for the next query?

Yes, you can. We provide QuerySelector and QuerySelectorAll methods; they accept your query expression object.

Caching a query expression object avoids recompiling the XPath query expression, improving query performance.

Create XML document.

doc := &xmlquery.Node{
	Type: xmlquery.DeclarationNode,
	Data: "xml",
	Attr: []xml.Attr{
		xml.Attr{Name: xml.Name{Local: "version"}, Value: "1.0"},
	},
}
root := &xmlquery.Node{
	Data: "rss",
	Type: xmlquery.ElementNode,
}
doc.FirstChild = root
channel := &xmlquery.Node{
	Data: "channel",
	Type: xmlquery.ElementNode,
}
root.FirstChild = channel
title := &xmlquery.Node{
	Data: "title",
	Type: xmlquery.ElementNode,
}
title_text := &xmlquery.Node{
	Data: "W3Schools Home Page",
	Type: xmlquery.TextNode,
}
title.FirstChild = title_text
channel.FirstChild = title
fmt.Println(doc.OutputXML(true))
// <?xml version="1.0"?><rss><channel><title>W3Schools Home Page</title></channel></rss>

Quick Tutorial

import (
	"github.com/antchfx/xmlquery"
)

func main(){
	s := `<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
  <title>W3Schools Home Page</title>
  <link>https://www.w3schools.com</link>
  <description>Free web building tutorials</description>
  <item>
    <title>RSS Tutorial</title>
    <link>https://www.w3schools.com/xml/xml_rss.asp</link>
    <description>New RSS tutorial on W3Schools</description>
  </item>
  <item>
    <title>XML Tutorial</title>
    <link>https://www.w3schools.com/xml</link>
    <description>New XML tutorial on W3Schools</description>
  </item>
</channel>
</rss>`

	doc, err := xmlquery.Parse(strings.NewReader(s))
	if err != nil {
		panic(err)
	}
	channel := xmlquery.FindOne(doc, "//channel")
	if n := channel.SelectElement("title"); n != nil {
		fmt.Printf("title: %s\n", n.InnerText())
	}
	if n := channel.SelectElement("link"); n != nil {
		fmt.Printf("link: %s\n", n.InnerText())
	}
	for i, n := range xmlquery.Find(doc, "//item/title") {
		fmt.Printf("#%d %s\n", i, n.InnerText())
	}
}

List of supported XPath query packages

Name Description
htmlquery XPath query package for HTML documents
xmlquery XPath query package for XML documents
jsonquery XPath query package for JSON documents

Questions

Please let me know if you have any questions

Owner
The open source web crawler framework project
null
Comments
  • Stream Parser Support - pt1 - add removeFromTree helper

    Stream Parser Support - pt1 - add removeFromTree helper

    This is pt1 of adding stream parser support. See original proof-of-concept PR at https://github.com/antchfx/xmlquery/pull/32.

    • Add removeFromTree helper. This is needed during the stream parsing: every time when we load and match a target node, we must remove the previous target node from the DOM tree (or otherwise it defeats the purpose of stream parsing to avoid memory constraints)

    • Add *Node and various type marshaling code in marshal_test.go for test snapshotting. The reason putting these in a _test.go file is to avoid adding them into the production code that would 'pollute' the library.

    • Add dependency to cupaloy for test snapshots.

    In the future, to update any test snapshots, simply add UPDATE_SNAPSHOTS=true env var:

    UPDATE_SNAPSHOTS=true go test ./...
    
  • Add streaming XML loading/parsing support

    Add streaming XML loading/parsing support

    BIG NOTE: this is just a proposal and proof of concept. Once consensus is reached, we can/will make the PR a lot more formal and rigorous.

    We have use cases where we need to load/parse large XML documents in streaming fashion to avoid memory constraints. Example XML:

    <AAA>
       <BBB>
          ....
          ....
       </BBB>
       <BBB>
          ....
          ....
       </BBB>
       ....
    </AAA>
    

    Currently we duplicate the node.go/parse() function in our own private repo and implement the stream parsing. As a result, we had to duplicate Node struct, as well as NodeNavigator impl.

    Thought if you want to take a look and consider if it's a use case others might benefit from?

    Limitations:

    • The streaming target xpath support is very very basic: /AAA/BBB only. I always wanted to stay away from using string, but instead a compiled *xpath.Expr. That way most of xpath features/functionalities (minus those XPATH directives involving position() etc) could be supported. The difficulty here is when I get an element *Node, how to evaluate it against the caller specified *xpath.Expr to see if the node "fits" the xpath? I could traverse the element node all the way to the top and then do select with the *xpath.Expr against the top node, but when the expr returns how do I know the returned node is the element node I'm interested in?

    • Due to the nature and purpose of streaming, every time when a target node is read and done processing by the caller, the very next StreamParser.Read() call would remove the previous target node from the DOM tree (otherwise, the DOM tree would eventually grow to the full extent of the XML document, which defeats the purpose of streaming). Now that's a bit unorthodox if you might say. Want to know what's your opinion here. The behavior described here fits our needs perfectly though.

    @zhengchun ^^

    PS we also have similar needs in jsonquery where we want to stream read a very large json document.

  • Create new XML from extraced nodes

    Create new XML from extraced nodes

    Can i create a new XML file frome the nodes I've extracted? I used n := xmlquery.FindOne(doc, "//part[@id='P1']") to get the part of the XML i needed. Now i want to write that part into a new xml file.

  • add cdata node type.

    add cdata node type.

    fixes #30.

    updated travis.yml to not test against golang 1.7 and 1.8 due to group cache pulling in math/bits which were not backported. (imo should just remove groupcache and add an internal/lru package to supply the 100 lines or so of code for the cache. but out of scope for this PR)

  • XML with namespace and expression with attribute filter

    XML with namespace and expression with attribute filter

    I don't know if I should open this issue here or on xpath, if it is wrong just let me know and I can close it here and open it there.

    With the example below it demonstrate that expression like //node[@attr='value'] will not work when xml uses namespace and you are selecting a node that belongs to this namespace.

    How can I make it work?

    package main
    
    import (
    	"fmt"
    	"os"
    	"strings"
    
    	"github.com/antchfx/xmlquery"
    )
    
    func main() {
    	willWork()
    	willFail()
    }
    
    func willWork() {
    	fmt.Println("### WILL WORK")
    
    	// Note: root node does not contain xmlns attribute
    	xmlInput := `<root>
    	  <myns:child id="1">value 1</myns:child>
    	  <myns:child id="2">value 2</myns:child>
    	</root>`
    
    	reader := strings.NewReader(xmlInput)
    	doc, err := xmlquery.Parse(reader)
    	if err != nil {
    		fmt.Println(err)
    		os.Exit(1)
    	}
    
    	node := xmlquery.Find(doc, "//child[@id='1']")
    	if node == nil {
    		fmt.Println("ERROR - Not found")
    	} else {
    		fmt.Println("GOOD - Found")
    		fmt.Println(len(node))
    	}
    
    	// Even though the expression above work, this one will fail
    	node = xmlquery.Find(doc, "//myns:child[@id='1']")
    	if node == nil {
    		fmt.Println("ERROR - Not found")
    	} else {
    		fmt.Println("GOOD - Found")
    		fmt.Println(len(node))
    	}
    }
    
    func willFail() {
    	fmt.Println("### WILL FAIL")
    
    	// Note: root node contains xmlns attribute
    	xmlInput := `<root xmlns:myns="bla bla bla">
    	  <myns:child id="1">value 1</myns:child>
    	  <myns:child id="2">value 2</myns:child>
    	</root>`
    
    	reader := strings.NewReader(xmlInput)
    	doc, err := xmlquery.Parse(reader)
    	if err != nil {
    		fmt.Println(err)
    		os.Exit(1)
    	}
    
    	node := xmlquery.Find(doc, "//child[@id='1']")
    	if node == nil {
    		fmt.Println("ERROR - Not found")
    	} else {
    		fmt.Println("GOOD - Found")
    		fmt.Println(len(node))
    	}
    
    	node = xmlquery.Find(doc, "//myns:child[@id='1']")
    	if node == nil {
    		fmt.Println("ERROR - Not found")
    	} else {
    		fmt.Println("GOOD - Found")
    		fmt.Println(len(node))
    	}
    
    	node = xmlquery.Find(doc, "//myns:child")
    	if node == nil {
    		fmt.Println("ERROR - Not found")
    	} else {
    		fmt.Println("GOOD - Found")
    		fmt.Println(len(node))
    	}
    }
    
  • Allowing injecting custom-configured decoder instance

    Allowing injecting custom-configured decoder instance

    Hello, and thank you for this package.

    For my usecase, I need to set the decoder settings to Strict = false. I saw that you commented here, and made the suggested changes. If you were to merge this, you can probably close #27 .

    Since the decoder needs to be injected a cachedReader, I did not find any other way than exposing the cachedReader object.

    This change also happens to help with my usecase, because I want to be able to jump to any element from it's offset (during a stream-parse) with reader.Seek, which breaks the caching system unless I can empty it.

  • Output XML does not preserve whitespace and this is no way configurable

    Output XML does not preserve whitespace and this is no way configurable

    the private function has a preserveSpaces option but this is not exposed in the private method,

    I feel like this is a basic feature which would be universally required, can we expose this parameter to the Public function?

    outputXML(buf *bytes.Buffer, n *Node, preserveSpaces bool) {

    our application turns xml into html and therefore spaces needs to be preserved, as a temp workaround we've hardcoded this value to true, however it seems like a more sustainable approach if this were configurable somehow or whether it could be an extra parameter

  • XPath 2.0 conditional expressions aren't supported

    XPath 2.0 conditional expressions aren't supported

    A sequential XPath expressions (XPath 2.0 standard) in a form (eval1, eval2) that returns all eval1 and then all eval2 causes panic with an error 'expression must evaluate to a node-set'. For example, the following code:

    s := `<?xml version="1.0" encoding="utf-8"?><root><element><sub>text1</sub><element>text2</element></root>`
    doc, err := xmlquery.Parse(strings.NewReader(s))
    nodes := doc.SelectElement(`//root/element/(sub, .[not(sub)])`)
    if len(nodes) != 2 {
      fmt.Print("failed!")
    }
    

    should return two nodes:

    - <sub>text1</sub>
    - <element>text2</element>
    
  • Extract tree traversing from FindOne()

    Extract tree traversing from FindOne()

    This allows for pre-compiling the expression before calling FindOne() repeatedly and makes any invalid expression handleable.

    use case

    We are trying to use this library for running the same xmlquery multiple times. Since the xmlquery is also user-provided we would like to handle any invalid expressions beforehand w/o having to handle panics. This PR allows us to compile the expression beforehand (and handle nicely) and apply it multiple times to multiple documents easily.

  • OutputXML should not call EscapeText when node type is TextNode.

    OutputXML should not call EscapeText when node type is TextNode.

    I think the OutputXML function should give same string as the xml file is shows, not escape text. Escape xml Attribute is enough.

    when xml is

    <?xml version="1.0" encoding="utf-8"?>
    	<class_list>
    		<student xml:space="preserve">
    			<name xml:space="default"> 
    			Robert 
    			</name>
    			<grade>A+</grade>
    		</student>
    	</class_list>`
    

    User except the node's OutputXML give the same string, not escape '\n\t' to html escape string.

    and I found xml will escape these string &\n\t to html &amp;. I think may be this is way you escape these string.

    I think TextNode may not need this escape behavior, only Attr string need this behavior.

    If you need a pr to fix this, I can create a pr. But this may break a lot of tests.

  • Skip text node only if empty

    Skip text node only if empty

    The fix in #45 skips non empty text nodes and results in the issue i reported in #61. This PR will skip only empty text nodes. I just used strings.TrimSpace() which will trim more than XSLT defines as non preserving whitespace. But this is probably the behaviour most users would expect. Otherwise i could only check for LF, CR, SP and HT.

  • Order of xmlns definitions affects parser's output

    Order of xmlns definitions affects parser's output

    I've encountered an issue, that xmlquery.FindOne(svgDocument, "//svg") was behaving correctly on some SVG documents, and not behaving correctly on other documents.

    The cause was a different order or xmlns definitions:

       xmlns="http://www.w3.org/2000/svg"
       xmlns:svg="http://www.w3.org/2000/svg"
    

    The full reproduction code:

    const svg01 = `
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <svg
       xmlns:svg="http://www.w3.org/2000/svg"
       xmlns="http://www.w3.org/2000/svg">
    </svg>`
    
    const svg02 = `
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <svg
       xmlns="http://www.w3.org/2000/svg"
       xmlns:svg="http://www.w3.org/2000/svg">
    </svg>`
    
    func Test01(t *testing.T) {
    	svgDocument, err := xmlquery.Parse(strings.NewReader(svg01))
    	assert.NilError(t, err)
    
    	fmt.Printf("svg: %s\n", svgDocument.OutputXML(true))
    
    	svgNode := xmlquery.FindOne(svgDocument, "//svg")
    	assert.Assert(t, svgNode != nil)
    }
    
    func Test02(t *testing.T) {
    	svgDocument, err := xmlquery.Parse(strings.NewReader(svg02))
    	assert.NilError(t, err)
    
    	fmt.Printf("svg: %s\n", svgDocument.OutputXML(true))
    
    	svgNode := xmlquery.FindOne(svgDocument, "//svg")
    	assert.Assert(t, svgNode != nil)
    }
    

    The output of OutputXML also differs:

    svg: <?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"></svg>
    
    svg: <?xml version="1.0" encoding="UTF-8" standalone="no"?><svg:svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"></svg:svg>
    

    The query can be executed against local-name() function:

    	svgNode := xmlquery.FindOne(svgDocument, `//*[local-name()="svg"]`)
    

    However, this would require all queries to be rewritten in this form. IMO, the parsing of a document shouldn't change namespace from default xmlns="http://www.w3.org/2000/svg" (unspecified for tags) to xmlns:svg="http://www.w3.org/2000/svg".

  • CVE-2022-41717

    CVE-2022-41717

    Trivy is identifying https://www.cvedetails.com/cve/CVE-2022-41717/ with golang.org/x/net, fix identified in 0.4.0

    Please consider updating go.mod to

    golang.org/x/net v0.4.0
    

    Thanks.

  • No error or panic when parsing non-XML

    No error or panic when parsing non-XML

    I was expecting Parse or Query to error out if I were to pass in something completely invalid, but it falls all the way through instead:

    func TestXmlParse_1(t *testing.T) {
    	//s := `<note>
    	//<to>John</to>
    	//<from>Smith</from>
    	//<heading>Reminder</heading>
    	//<body>Don't forget me this weekend!</body>
    	//</note>`
    
    	s := `{"NotXml":"ActuallyJson"}`
    
    	parse, err := xmlquery.Parse(strings.NewReader(s))
    	if err != nil {
    		println(err.Error())
    		t.Fail()
    	}
    	query, err := xmlquery.Query(parse, "//body/text()")
    	if err != nil {
    		println(err.Error())
    		t.Fail()
    	}
    	println(query.Data)
    
    }
    

    using:

    • github.com/antchfx/xmlquery v1.3.11
  • [Feature Request] `OutputXML` supports setting `calculatePreserveSpaces` to true

    [Feature Request] `OutputXML` supports setting `calculatePreserveSpaces` to true

    https://github.com/antchfx/xmlquery/blob/13877b8180f038f701a5474cbdb368bf068fdb5f/node.go#L144

    Hi! Can you support these parameters? I would like to keep the original format :)

  • XML syntax error on line 9: unescaped < inside quoted string

    XML syntax error on line 9: unescaped < inside quoted string

    XML:

    <MatchCfg>
        <ConfirmTimeOutPunish Time="2" />
        <MatchRoom MaxLoop="100" />
        <MatchPlayer MaxLoop="100" />
        <MatchStatInfo ReportInterval="5"/>
    
        <TABLEAU>
            <META>
                <MatchMode MissionType="enum<.MissionType>" desc="string">
                    <Time MinTime="duration" MaxTime="duration" Freq="int" ConfirmTime="int" />
                    <Open BeginDate="date" BeginTime="time"  EndDate="date" EndTime="time" />
                    <Camp  TYPE="repeated" CampID="uint32" PlayerNum="int" desc="string" />
                    <Strategy StrategyID="enum<.ENMMatchStrategy>" desc="string" />
    
                    <Scope    ScopeID="enum<.ENMMatchScope>"  desc="string" />
                    <Filter TYPE="repeated" FilterID="enum<.ENMMatchFilter>" Open="bool" Value="int"  UpdInterval="duratioin" desc="string">
                        <Power TYPE="repeated" HornorPower="int">
                            <Param TYPE="repeated" Value="int"/>
                        </Power>
                    </Filter>
                    <Route    Key="int" desc="string" />
                    <!-- PlayerOnlyOneCamp: 匹配到AI的玩家都在一个阵营 GuaranteeAIRatio:保底AI概率万分比 -->
                    <MatchAI IsOpen="bool" PlayerOnlyOneCamp="bool" GuaranteeAIRatio="int">
                        <AI Type="enum<.ENMAIWarmType>" IsOpen="bool" MinTime="duration" MaxTime="duration"  desc="string" />
                    </MatchAI>
                    <!-- 优先级, 随机模式随机先后顺序的权重,用于控制随机模式各个模式的比例 -->
                    <Random MissionType="enum<.MissionType>" Priority="int" />
                </MatchMode>
            </META>
        </TABLEAU>
    </MatchCfg>
    

    My code:

    atom.Log.Debugf("xml: %s", xmlPath)
    f, err := os.Open(xmlPath)
    if err != nil {
    return errors.Wrapf(err, "failed to open %s", xmlPath)
    }
    p, err := xmlquery.CreateStreamParser(f, "/")
    if err != nil {
    return errors.Wrapf(err, "failed to create parsee for file %s", xmlPath)
    }
    n, err := p.Read()
    if err != nil {
    return errors.Wrapf(err, "failed to read from file %s", xmlPath)
    }
    root := xmlquery.CreateXPathNavigator(n)
    

    Error:

    2022-01-19T14:59:57.061+0800|ERROR|tableau/tableau.go:75|generate failed: XML syntax error on line 14: unescaped < inside quoted string
    failed to read from file testdata/xml/match/Match.xml
    github.com/Wenchy/tableau/internal/protogen.(*XmlGenerator).convert
            /data/home/user00/Git/tableau/internal/protogen/protogen.go:333
    github.com/Wenchy/tableau/internal/protogen.(*Generator).convert
            /data/home/user00/Git/tableau/internal/protogen/protogen.go:149
    github.com/Wenchy/tableau/internal/protogen.(*Generator).generate
            /data/home/user00/Git/tableau/internal/protogen/protogen.go:141
    github.com/Wenchy/tableau/internal/protogen.(*Generator).generate
            /data/home/user00/Git/tableau/internal/protogen/protogen.go:126
    github.com/Wenchy/tableau/internal/protogen.(*Generator).Generate
            /data/home/user00/Git/tableau/internal/protogen/protogen.go:114
    github.com/Wenchy/tableau.Xml2Proto
            /data/home/user00/Git/tableau/tableau.go:74
    github.com/Wenchy/tableau/test.Test_Xml2Proto
            /data/home/user00/Git/tableau/test/tableau_test.go:59
    testing.tRunner
            /usr/local/go/src/testing/testing.go:1194
    runtime.goexit
            /usr/local/go/src/runtime/asm_amd64.s:1371
    

    As my point of view, < which is inside quotes should be allowed to construct an attribute value, but the errors above occur. Any way to let me use the characters < and > in attribute values?

An (almost) compliant XPath 1.0 library.

xsel xsel is a library that (almost) implements the XPath 1.0 specification. The non-compliant bits are: xsel does not implement the id function. The

Dec 21, 2022
Sqly - An easy-to-use extension for sqlx, base on xml files and named query/exec

sqly An easy-to-use extension for sqlx ,base on xml files and named query/exec t

Jun 12, 2022
This package provides Go (golang) types and helper functions to do some basic but useful things with mxGraph diagrams in XML, which is most famously used by app.diagrams.net, the new name of draw.io.

Go Draw - Golang MX This package provides types and helper functions to do some basic but useful things with mxGraph diagrams in XML, which is most fa

Aug 30, 2022
omniparser: a native Golang ETL streaming parser and transform library for CSV, JSON, XML, EDI, text, etc.
omniparser: a native Golang ETL streaming parser and transform library for CSV, JSON, XML, EDI, text, etc.

omniparser Omniparser is a native Golang ETL parser that ingests input data of various formats (CSV, txt, fixed length/width, XML, EDI/X12/EDIFACT, JS

Jan 4, 2023
Freestyle xml parser with golang

fxml - FreeStyle XML Parser This package provides a simple parser which reads a XML document and output a tree structure, which does not need a pre-de

Jul 1, 2022
Decode / encode XML to/from map[string]interface{} (or JSON); extract values with dot-notation paths and wildcards. Replaces x2j and j2x packages.

mxj - to/from maps, XML and JSON Decode/encode XML to/from map[string]interface{} (or JSON) values, and extract/modify values from maps by key or key-

Dec 29, 2022
Convert xml and json to go struct

xj2go The goal is to convert xml or json file to go struct file. Usage Download and install it: $ go get -u -v github.com/wk30/xj2go/cmd/... $ xj [-t

Oct 23, 2022
parse and generate XML easily in go

etree The etree package is a lightweight, pure go package that expresses XML in the form of an element tree. Its design was inspired by the Python Ele

Dec 19, 2022
'go test' runner with output optimized for humans, JUnit XML for CI integration, and a summary of the test results.
'go test' runner with output optimized for humans, JUnit XML for CI integration, and a summary of the test results.

gotestsum gotestsum runs tests using go test --json, prints formatted test output, and a summary of the test run. It is designed to work well for both

Dec 28, 2022
Go XML sitemap and sitemap index generator

Install go get github.com/turk/go-sitemap Example for sitemapindex func () main(c *gin.Context) { s := sitemap.NewSitemapIndex(c.Writer, true)

Jun 29, 2022
Extraction politique de conformité : xlsx (fichier de suivi) -> xml (format AlgoSec)

go_policyExtractor Extraction politique de conformité : xlsx (fichier de suivi) -> xml (format AlgoSec). Le programme suivant se base sur les intitulé

Nov 4, 2021
axmlfmt is an opinionated formatter for Android XML resources

axmlfmt axmlfmt is an opinionated formatter for Android XML resources. It takes XML that looks like <?xml version="1.0" encoding="utf-8"?> <LinearLayo

May 14, 2022
🧑‍💻 Go XML generator without Structs™

exml ??‍?? Go XML generator without Structs™ Package exml allows XML documents to be generated without the usage of structs or maps. It is not intende

Nov 15, 2022
wikipedia-jsonl is a CLI that converts Wikipedia dump XML to JSON Lines format.

wikipedia-jsonl wikipedia-jsonl is a CLI that converts Wikipedia dump XML to JSON Lines format. How to use At first, download the XML dump from Wikime

Dec 26, 2022
Quick and simple parser for PFSense XML configuration files, good for auditing firewall rules

pfcfg-parser version 0.0.1 : 13 January 2022 A quick and simple parser for PFSense XML configuration files to generate a plain text file of the main c

Jan 13, 2022
A golang package to work with Decentralized Identifiers (DIDs)

did did is a Go package that provides tools to work with Decentralized Identifiers (DIDs). Install go get github.com/ockam-network/did Example packag

Nov 25, 2022
Go (Golang) GNU gettext utilities package

Gotext GNU gettext utilities for Go. Features Implements GNU gettext support in native Go. Complete support for PO files including: Support for multil

Dec 18, 2022
Package sanitize provides functions for sanitizing text in golang strings.

sanitize Package sanitize provides functions to sanitize html and paths with go (golang). FUNCTIONS sanitize.Accents(s string) string Accents replaces

Dec 5, 2022
A minimalistic emoji package for Go (golang)

emoji ?? ?? ?? emoji is a minimalistic emoji library for Go. It lets you use emoji characters in strings. Inspired by spatie/emoji Install ?? go get g

Dec 14, 2022