CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-ncclient

Python library for NETCONF clients with support for SSH, TLS, and device-specific operations

Pending
Overview
Eval results
Files

xml-utilities.mddocs/

XML Utilities

Tools for creating, parsing, and manipulating XML documents and NETCONF payloads. NCClient provides a comprehensive XML toolkit with namespace support, NETCONF-specific helpers, and efficient parsing capabilities.

Capabilities

XML Element Creation

Functions for creating XML elements and building XML documents programmatically.

def new_ele(tag, attrs=None, **extra):
    """
    Create new XML element.
    
    Parameters:
    - tag: str, element tag name (may include namespace)
    - attrs: dict, element attributes
    - **extra: additional attributes as keyword arguments
    
    Returns:
    Element: New XML element
    """

def new_ele_ns(tag, ns, attrs=None, **extra):
    """
    Create new XML element with explicit namespace.
    
    Parameters:
    - tag: str, element tag name
    - ns: str, namespace URI
    - attrs: dict, element attributes  
    - **extra: additional attributes as keyword arguments
    
    Returns:
    Element: New namespaced XML element
    """

def sub_ele(parent, tag, attrs=None, **extra):
    """
    Create XML sub-element under parent.
    
    Parameters:
    - parent: Element, parent element
    - tag: str, sub-element tag name
    - attrs: dict, element attributes
    - **extra: additional attributes as keyword arguments
    
    Returns:
    Element: New sub-element
    """

def sub_ele_ns(parent, tag, ns, attrs=None, **extra):
    """
    Create namespaced XML sub-element under parent.
    
    Parameters:
    - parent: Element, parent element
    - tag: str, sub-element tag name
    - ns: str, namespace URI
    - attrs: dict, element attributes
    - **extra: additional attributes as keyword arguments
    
    Returns:
    Element: New namespaced sub-element
    """

XML Parsing

Functions for parsing XML documents and converting between formats.

def parse_root(raw):
    """
    Parse XML document and return root element.
    
    Parameters:
    - raw: str or bytes, XML document content
    
    Returns:
    Element: Root element of parsed document
    """

def to_xml(ele, encoding="UTF-8", pretty_print=False):
    """
    Convert XML element to string representation.
    
    Parameters:
    - ele: Element, XML element to convert
    - encoding: str, character encoding (default UTF-8)
    - pretty_print: bool, format with indentation
    
    Returns:
    str: XML string representation
    """

def to_ele(x):
    """
    Convert various inputs to XML element.
    
    Parameters:
    - x: str, bytes, file-like object, or Element
    
    Returns:
    Element: XML element
    """

XML Validation and Utilities

Helper functions for XML validation and manipulation.

def validate_xml(xml_string, schema=None):
    """
    Validate XML against schema.
    
    Parameters:
    - xml_string: str, XML content to validate
    - schema: Schema object, validation schema (optional)
    
    Returns:  
    bool: True if valid, False otherwise
    """

def unqualify(tag):
    """
    Remove namespace qualification from tag name.
    
    Parameters:
    - tag: str, qualified tag name
    
    Returns:
    str: Unqualified tag name
    """

def qualify(tag, ns=None):
    """
    Add namespace qualification to tag name.
    
    Parameters:
    - tag: str, tag name to qualify
    - ns: str, namespace URI
    
    Returns:
    str: Qualified tag name
    """

XML Parsers

Parser objects for handling different XML processing requirements.

# Standard XML parser
parser = etree.XMLParser(recover=False)

# Parser with huge tree support for large documents
huge_parser = etree.XMLParser(recover=False, huge_tree=True)

def _get_parser(huge_tree=False):
    """
    Get appropriate parser based on requirements.
    
    Parameters:
    - huge_tree: bool, whether to use huge tree support
    
    Returns:
    XMLParser: Configured XML parser
    """

Namespace Constants

Predefined namespace URIs for common NETCONF and network management schemas.

# Base NETCONF namespace (RFC 6241)
BASE_NS_1_0 = "urn:ietf:params:xml:ns:netconf:base:1.0"

# YANG namespace (RFC 6020/7950)  
YANG_NS_1_0 = "urn:ietf:params:xml:ns:yang:1"

# Cisco NXOS namespaces
NXOS_1_0 = "http://www.cisco.com/nxos:1.0"
NXOS_IF = "http://www.cisco.com/nxos:1.0:if_manager"
CISCO_CPI_1_0 = "http://www.cisco.com/cpi_10/schema"

# Juniper namespace
JUNIPER_1_1 = "http://xml.juniper.net/xnm/1.1/xnm"

# Huawei namespaces
HUAWEI_NS = "http://www.huawei.com/netconf/vrp"
HW_PRIVATE_NS = "http://www.huawei.com/netconf/capability/base/1.0"

# H3C namespaces
H3C_DATA_1_0 = "http://www.h3c.com/netconf/data:1.0"
H3C_CONFIG_1_0 = "http://www.h3c.com/netconf/config:1.0"
H3C_ACTION_1_0 = "http://www.h3c.com/netconf/action:1.0"

# Nokia/Alcatel-Lucent namespaces
ALU_CONFIG = "urn:alcatel-lucent.com:sros:ns:yang:conf-r13"
SROS_GLOBAL_OPS_NS = "urn:nokia.com:sros:ns:yang:sr:oper-global"

# NETCONF standard namespaces
NETCONF_MONITORING_NS = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"
NETCONF_NOTIFICATION_NS = "urn:ietf:params:xml:ns:netconf:notification:1.0"
NETCONF_WITH_DEFAULTS_NS = "urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults"

# Tail-f namespaces
TAILF_AAA_1_1 = "http://tail-f.com/ns/aaa/1.1"
TAILF_EXECD_1_1 = "http://tail-f.com/ns/execd/1.1"

# Flowmon namespace
FLOWMON_1_0 = "http://www.liberouter.org/ns/netopeer/flowmon/1.0"

XML Error Handling

Exception classes for XML processing errors.

class XMLError(NCClientError):
    """Exception for XML processing errors."""
    
    def __init__(self, message, xml_content=None):
        """
        Initialize XML error.
        
        Parameters:
        - message: str, error description
        - xml_content: str, XML content that caused error (optional)
        """

NETCONF XML Helpers

Specialized functions for NETCONF-specific XML operations.

def build_filter(spec, filter_type="subtree"):
    """
    Build NETCONF filter element.
    
    Parameters:
    - spec: str or tuple, filter specification
    - filter_type: str, filter type ('subtree' or 'xpath')
    
    Returns:
    Element: NETCONF filter element
    """

def build_rpc(operation, *args, **kwargs):
    """
    Build NETCONF RPC element.
    
    Parameters:
    - operation: str, RPC operation name
    - *args: positional arguments for operation
    - **kwargs: keyword arguments for operation
    
    Returns:
    Element: NETCONF RPC element
    """

def wrap_rpc_reply(data):
    """
    Wrap data in NETCONF RPC reply envelope.
    
    Parameters:
    - data: Element, reply data content
    
    Returns:
    Element: NETCONF rpc-reply element
    """

Usage Examples

Creating XML Elements

from ncclient.xml_ import new_ele, sub_ele, to_xml

# Create root element
config = new_ele("config")

# Add sub-elements
interface = sub_ele(config, "interface")
sub_ele(interface, "name").text = "eth0"
sub_ele(interface, "description").text = "Management Interface"

# Convert to XML string
xml_string = to_xml(config, pretty_print=True)
print(xml_string)

Working with Namespaces

from ncclient.xml_ import new_ele_ns, sub_ele_ns, BASE_NS_1_0

# Create namespaced elements
rpc = new_ele_ns("rpc", BASE_NS_1_0, {"message-id": "101"})
get_config = sub_ele_ns(rpc, "get-config", BASE_NS_1_0)
source = sub_ele_ns(get_config, "source", BASE_NS_1_0)
sub_ele_ns(source, "running", BASE_NS_1_0)

print(to_xml(rpc, pretty_print=True))

Parsing XML Documents

from ncclient.xml_ import parse_root, to_ele

# Parse XML from string
xml_data = '''
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <data>
        <interfaces>
            <interface>
                <name>eth0</name>
                <type>ethernet</type>
            </interface>
        </interfaces>
    </data>
</rpc-reply>
'''

# Parse and extract data
root = parse_root(xml_data)
data = root.find(".//{urn:ietf:params:xml:ns:netconf:base:1.0}data")

# Work with parsed elements
interfaces = data.find(".//interfaces")
for interface in interfaces.findall(".//interface"):
    name = interface.find("name").text
    iface_type = interface.find("type").text
    print(f"Interface: {name}, Type: {iface_type}")

Building NETCONF Filters

from ncclient.xml_ import build_filter, new_ele, sub_ele

# Subtree filter
filter_spec = '''
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
    <interface>
        <name/>
        <type/>
        <admin-status/>
    </interface>
</interfaces>
'''

# Build filter element
filter_elem = build_filter(filter_spec, "subtree")

# XPath filter
xpath_filter = "/interfaces/interface[name='eth0']"
xpath_elem = build_filter(xpath_filter, "xpath")

Custom XML Processing

from ncclient.xml_ import parse_root, new_ele, sub_ele, to_xml

def extract_interface_config(config_xml):
    """Extract interface configuration from NETCONF data."""
    root = parse_root(config_xml)
    interfaces = []
    
    # Find all interface elements
    for interface in root.findall(".//interface"):
        interface_data = {
            'name': interface.find("name").text if interface.find("name") is not None else None,
            'description': interface.find("description").text if interface.find("description") is not None else None,
            'admin_status': interface.find("admin-status").text if interface.find("admin-status") is not None else None
        }
        interfaces.append(interface_data)
    
    return interfaces

def build_interface_config(interface_data):
    """Build interface configuration XML."""
    config = new_ele("config")
    interfaces = sub_ele(config, "interfaces")
    
    for iface in interface_data:
        interface = sub_ele(interfaces, "interface")
        sub_ele(interface, "name").text = iface['name']
        if iface.get('description'):
            sub_ele(interface, "description").text = iface['description']
        if iface.get('admin_status'):
            sub_ele(interface, "admin-status").text = iface['admin_status']
    
    return to_xml(config, pretty_print=True)

# Usage
config_data = [
    {'name': 'eth0', 'description': 'Management', 'admin_status': 'up'},
    {'name': 'eth1', 'description': 'Data', 'admin_status': 'up'}
]

xml_config = build_interface_config(config_data)
print(xml_config)

Error Handling

from ncclient.xml_ import parse_root, XMLError

def safe_parse_xml(xml_string):
    """Safely parse XML with error handling."""
    try:
        root = parse_root(xml_string)
        return root
    except XMLError as e:
        print(f"XML parsing error: {e}")
        return None
    except Exception as e:
        print(f"Unexpected error: {e}")
        return None

# Parse potentially malformed XML
malformed_xml = "<config><interface><name>eth0</interface></config>"  # Missing closing tag
result = safe_parse_xml(malformed_xml)
if result is None:
    print("Failed to parse XML")

Working with Large XML Documents

from ncclient.xml_ import _get_parser, etree

def parse_large_xml(xml_data):
    """Parse large XML documents with huge tree support."""
    parser = _get_parser(huge_tree=True)
    
    try:
        root = etree.fromstring(xml_data, parser)
        return root
    except etree.XMLSyntaxError as e:
        print(f"XML syntax error: {e}")
        return None

# Process large configuration files
large_xml_data = open('large_config.xml', 'rb').read()
root = parse_large_xml(large_xml_data)
if root is not None:
    print(f"Parsed large XML with {len(root)} child elements")

Install with Tessl CLI

npx tessl i tessl/pypi-ncclient

docs

connection-management.md

device-support.md

index.md

netconf-operations.md

transport-layer.md

xml-utilities.md

tile.json