xmlsurf

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2025 License: MIT Imports: 8 Imported by: 0

README

xmlsurf

A modern and efficient Go library for XML processing that provides a simple way to work with XML data using XPath-style paths.

Features

  • Convert XML to and from a map structure using XPath-style paths
  • Support for XML namespaces
  • Attribute handling
  • Value transformations
  • Indented XML output
  • Comprehensive error handling
  • Order-independent comparison of XML structures
  • Memory-efficient with optimized string operations
  • Modular, well-structured codebase for maintainability

Installation

go get github.com/bmcszk/[email protected]

Quick Start

package main

import (
    "fmt"
    "strings"
    "github.com/bmcszk/xmlsurf"
)

func main() {
    // Parse XML to map
    xml := `<root>
        <item id="1">first</item>
        <item id="2">second</item>
    </root>`
    
    result, err := xmlsurf.ParseToMap(strings.NewReader(xml))
    if err != nil {
        panic(err)
    }
    
    // Access values using XPath-style paths
    fmt.Println(result["/root/item[1]"])     // Output: first
    fmt.Println(result["/root/item[2]"])     // Output: second
    fmt.Println(result["/root/item[1]/@id"]) // Output: 1
    fmt.Println(result["/root/item[2]/@id"]) // Output: 2
    
    // Convert back to XML
    var buf strings.Builder
    err = result.ToXML(&buf, true) // true for indented output
    if err != nil {
        panic(err)
    }
    fmt.Println(buf.String())
}

Options

Namespace Handling
// Include namespace prefixes in element and attribute names
result, err := xmlsurf.ParseToMap(reader, xmlsurf.WithNamespaces(true))

// Exclude namespace prefixes
result, err := xmlsurf.ParseToMap(reader, xmlsurf.WithNamespaces(false))
Value Transformations
// Transform values during parsing
result, err := xmlsurf.ParseToMap(reader, 
    xmlsurf.WithValueTransform(strings.ToUpper),
    xmlsurf.WithValueTransform(strings.TrimSpace),
)

Comparison Methods

// Exact comparison (order matters)
equal := map1.Equal(map2)

// Order-independent comparison
equal := map1.EqualIgnoreOrder(map2)

// Get detailed differences between XMLMaps
diffs := map1.Diffs(map2)
for _, diff := range diffs {
    fmt.Println(diff.String()) // Human-readable description of the difference
}

// Get detailed differences ignoring element order
diffs := map1.DiffsIgnoreOrder(map2)

The Diff struct provides detailed information about differences between XML maps:

type Diff struct {
    Path       string   // The XPath where the difference was found
    LeftValue  string   // Value in the left XMLMap (empty if path doesn't exist)
    RightValue string   // Value in the right XMLMap (empty if path doesn't exist)
    Type       DiffType // Type of difference (DiffMissing, DiffExtra, or DiffValue)
}

Diff types:

  • DiffMissing - Path exists in right but not in left
  • DiffExtra - Path exists in left but not in right
  • DiffValue - Path exists in both but values differ

Path Representation

The XMLMap uses XPath-like path expressions as keys:

  • Basic element paths: /root/child
  • Element indices for repeated elements: /root/items/item[1], /root/items/item[2]
  • Attribute paths: /root/element/@attribute
  • Namespaced elements: /ns:root/ns:child

Implementation Details

The library has been optimized for performance and memory efficiency:

  • Uses a string builder pool to minimize memory allocations
  • Pre-allocates collections with appropriate initial sizes
  • Efficiently handles element repetition with automatic indexing
  • Optimized string operations to reduce concatenation overhead
  • Modular, well-organized code structure for maintainability

Error Handling

The library provides detailed error messages for various XML parsing scenarios:

  • Invalid XML syntax
  • Unclosed elements
  • Multiple root elements
  • Malformed attributes
  • Invalid element names

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Diff added in v1.0.1

type Diff struct {
	Path       string   // The XPath where the difference was found
	LeftValue  string   // Value in the left XMLMap (empty if path doesn't exist)
	RightValue string   // Value in the right XMLMap (empty if path doesn't exist)
	Type       DiffType // Type of difference
}

Diff represents a difference between two XMLMaps

func (Diff) String added in v1.0.1

func (d Diff) String() string

String returns a human-readable description of the difference

type DiffType added in v1.0.1

type DiffType int

DiffType indicates the type of difference between XMLMaps

const (
	// DiffMissing indicates a path exists in right but not in left
	DiffMissing DiffType = iota
	// DiffExtra indicates a path exists in left but not in right
	DiffExtra
	// DiffValue indicates a path exists in both but values differ
	DiffValue
)

type Option

type Option func(*ParseOptions)

Option is a function that configures ParseOptions

func WithNamespaces

func WithNamespaces(include bool) Option

WithNamespaces returns an Option that enables namespace prefix inclusion

func WithValueTransform

func WithValueTransform(transform func(string) string) Option

WithValueTransform returns an Option that sets a function to transform values during parsing

type ParseOptions

type ParseOptions struct {
	// IncludeNamespaces controls whether namespace prefixes should be included in element and attribute names
	IncludeNamespaces bool
	// ValueTransform is a function that transforms each value during parsing
	ValueTransform func(string) string
}

ParseOptions configures how XML should be parsed

func DefaultParseOptions

func DefaultParseOptions() *ParseOptions

DefaultParseOptions returns the default parsing options

type XMLMap

type XMLMap map[string]string

XMLMap represents a map of XPath expressions to their values

func ParseToMap

func ParseToMap(reader io.Reader, opts ...Option) (XMLMap, error)

ParseToMap parses XML from the reader and returns a map of XPath expressions to values. It accepts optional configuration through Option functions. The resulting map contains XPath expressions as keys and their corresponding values. For elements with attributes, the attribute paths are prefixed with "@". For repeated elements, indices are added to the path (e.g., /root/item[1], /root/item[2]).

func (XMLMap) Diffs added in v1.0.1

func (m XMLMap) Diffs(other XMLMap) []Diff

Diffs returns a list of differences between two XMLMaps It compares exact paths and values, considering element order

func (XMLMap) DiffsIgnoreOrder added in v1.0.1

func (m XMLMap) DiffsIgnoreOrder(other XMLMap) []Diff

DiffsIgnoreOrder returns a list of differences between two XMLMaps, ignoring element order

func (XMLMap) Equal

func (m XMLMap) Equal(other XMLMap) bool

Equal returns true if two XMLMaps are equal

func (XMLMap) EqualIgnoreOrder

func (m XMLMap) EqualIgnoreOrder(other XMLMap) bool

EqualIgnoreOrder returns true if two XMLMaps are equal ignoring the order of elements

func (XMLMap) ToXML

func (m XMLMap) ToXML(w io.Writer, indent bool) error

ToXML converts the XMLMap to XML and writes it to the provided writer. The XML will be indented if indent is true.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL