Element

Struct Element 

Source
pub struct Element { /* private fields */ }
Expand description

Represents an XML element. It acts as a pointer to actual element data stored in Document.

This struct only contains a unique usize id and implements trait Copy. So you do not need to bother with having a reference.

Because the actual data of the element is stored in Document, most methods takes &Document or &mut Document as its first argument.

Note that an element may only interact with elements of the same document, but the crate doesn’t know which document an element is from. Trying to push an element from a different Document may result in unexpected errors.

§Examples

Find children nodes with attribute

use biodivine_xml_doc::{Document, Element};

let doc = Document::parse_str(r#"<?xml version="1.0"?>
<data>
  <item class="value">a</item>
  <item class="value">b</item>
  <item></item>
</data>
"#).unwrap();

let data = doc.root_element().unwrap();
let value_items: Vec<Element> = data.children(&doc)
    .iter()
    .filter_map(|node| node.as_element())
    .filter(|elem| elem.attribute(&doc, "class") == Some("value"))
    .collect();

Implementations§

Source§

impl Element

Source

pub fn new<S: Into<String>>(doc: &mut Document, full_name: S) -> Self

Create a new empty element with full_name.

If full_name contains :, everything before that will be interpreted as a namespace prefix.

Source

pub fn build<S: Into<String>>(name: S) -> ElementBuilder

Chain methods to build an element easily. The chain can be finished with .finish() or .push_to(parent).

§Example
use biodivine_xml_doc::{Document, Element, Node};

let mut doc = Document::new();

let elem = Element::build("root")
    .attribute("id", "main")
    .attribute("class", "main")
    .finish(&mut doc);

doc.push_root_node(elem.as_node()).unwrap();
Source

pub fn is_container(&self) -> bool

Returns true if element is a container.

See Document::container() for more information on ‘container’.

Source

pub fn as_node(&self) -> Node

Equivalent to Node::Element(self)

Source

pub fn separate_prefix_name(full_name: &str) -> (&str, &str)

Seperate full_name by :, returning (prefix, name).

The first str is "" if full_name has no prefix.

Source§

impl Element

Below are methods that take &Document as its first argument.

Source

pub fn is_root(&self, doc: &Document) -> bool

Returns true if this element is the root node of document.

Note that this crate allows Document to have multiple elements, even though it’s not valid xml.

Source

pub fn top_parent(&self, doc: &Document) -> Element

Returns the “top” parent of this element. If the element is attached, the “top” parent is the document root. Otherwise, the “top” parent is the root of the detached sub-tree.

Source

pub fn full_name<'a>(&self, doc: &'a Document) -> &'a str

Get full name of element, including its namespace prefix. Use Element::name() to get its name without the prefix.

Source

pub fn set_full_name<S: Into<String>>(&self, doc: &mut Document, name: S)

Source

pub fn prefix_name<'a>(&self, doc: &'a Document) -> (&'a str, &'a str)

Get prefix and name of element. If it doesn’t have prefix, will return an empty string.

<prefix: name -> ("prefix", "name")

Source

pub fn prefix<'a>(&self, doc: &'a Document) -> &'a str

Get namespace prefix of element, without name.

<prefix:name> -> "prefix"

Source

pub fn set_prefix<S: Into<String>>(&self, doc: &mut Document, prefix: S)

Set prefix of element, preserving its name.

prefix should not have a :, or everything after : will be interpreted as part of element name.

If prefix is an empty string, removes prefix.

Source

pub fn name<'a>(&self, doc: &'a Document) -> &'a str

Get name of element, without its namespace prefix. Use Element::full_name() to get its full name with prefix.

<prefix:name> -> "name"

Source

pub fn set_name<S: Into<String>>(&self, doc: &mut Document, name: S)

Set name of element, preserving its prefix.

name should not have a :, or everything before : may be interpreted as namespace prefix.

Source

pub fn attributes<'a>(&self, doc: &'a Document) -> &'a HashMap<String, String>

Get attributes of element.

The attribute names may have namespace prefix. To strip the prefix and only its name, call Element::separate_prefix_name.

use biodivine_xml_doc::{Document, Element};

let mut doc = Document::new();
let element = Element::build("name")
    .attribute("id", "name")
    .attribute("pre:name", "value")
    .finish(&mut doc);

let attrs = element.attributes(&doc);
for (full_name, value) in attrs {
    let (prefix, name) = Element::separate_prefix_name(full_name);
    // ("", "id"), ("pre", "name")
}
Source

pub fn attribute<'a>(&self, doc: &'a Document, name: &str) -> Option<&'a str>

Get attribute value of an element by its full name. (Namespace prefix isn’t stripped)

Source

pub fn set_attribute<S, T>(&self, doc: &mut Document, name: S, value: T)
where S: Into<String>, T: Into<String>,

Add or set attribute.

If name contains a :, everything before : will be interpreted as namespace prefix.

Source

pub fn mut_attributes<'a>( &self, doc: &'a mut Document, ) -> &'a mut HashMap<String, String>

Source

pub fn namespace<'a>(&self, doc: &'a Document) -> Option<&'a str>

Gets the namespace of this element.

Shorthand for self.namespace_for_prefix(doc, self.prefix(doc)).

Source

pub fn namespace_decls<'a>( &self, doc: &'a Document, ) -> &'a HashMap<String, String>

Gets HashMap of xmlns:prefix=namespace declared in this element’s attributes.

Default namespace has empty string as key.

Source

pub fn mut_namespace_decls<'a>( &self, doc: &'a mut Document, ) -> &'a mut HashMap<String, String>

Source

pub fn set_namespace_decl<S, T>( &self, doc: &mut Document, prefix: S, namespace: T, )
where S: Into<String>, T: Into<String>,

Source

pub fn namespace_for_prefix<'a>( &self, doc: &'a Document, prefix: &str, ) -> Option<&'a str>

Get namespace value given prefix, for this element. “xml” and “xmlns” returns its default namespace.

This method can return an empty namespace, but only for an empty prefix assuming there is no default namespace declared.

Source

pub fn is_quantified(&self, doc: &Document, namespace_url: &str) -> bool

Returns true if this element is quantified by the given namespace_url. That is, either its prefix resolves to this namespace, or this is the default namespace in this context.

See also the usage example in Self::quantify_with_closest.

Source

pub fn quantify_with_closest( &self, doc: &mut Document, namespace_url: &str, ) -> Option<String>

Ensure that this element belongs to the specified namespace using the closest prefix which corresponds to the given namespace_url.

If the namespace is not declared for this element, returns None, otherwise returns the new prefix. As such, None actually represents an error and must be consumed.

See Self::closest_prefix for the definitions of which prefix will be used.

use biodivine_xml_doc::Document;

let mut doc = Document::parse_str(r#"<?xml version="1.0" encoding="UTF-8"?>
<parent xmlns="http://ns1" xmlns:ns1="http://ns1" xmlns:ns2="http://ns2">
    <child xmlns:ns="http://ns2" />
</parent>
"#).unwrap();

let root = doc.root_element().unwrap();
let child = root.child_elements(&doc)[0];

// Everybody is already quantified with ns1, since it is the default namespace.

assert!(child.is_quantified(&doc, "http://ns1"));
assert!(!root.is_quantified(&doc, "http://ns2"));

assert_eq!(child.quantify_with_closest(&mut doc, "http://ns1"), Some("".to_string()));
assert_eq!(root.quantify_with_closest(&mut doc, "http://ns2"), Some("ns2".to_string()));

assert!(child.is_quantified(&doc, "http://ns1"));
assert!(root.is_quantified(&doc, "http://ns2"));
Source

pub fn text_content(&self, doc: &Document) -> String

Concatenate all text content of this element, including its child elements text_content().

Implementation of Node.textContent

Source

pub fn set_text_content<S: Into<String>>(&self, doc: &mut Document, text: S)

Clears all its children and inserts a Node::Text with given text.

Source§

impl Element

Below are methods related to finding nodes in tree.

Source

pub fn parent(&self, doc: &Document) -> Option<Element>

Source

pub fn has_parent(&self, doc: &Document) -> bool

self.parent(doc).is_some()

Source

pub fn children<'a>(&self, doc: &'a Document) -> &'a Vec<Node>

Get child Nodes of this element.

Source

pub fn children_recursive<'a>(&self, doc: &'a Document) -> Vec<&'a Node>

Get all child nodes recursively. (i.e. includes its children’s children.)

Source

pub fn has_children(&self, doc: &Document) -> bool

!self.children(doc).is_empty()

Source

pub fn child_elements(&self, doc: &Document) -> Vec<Element>

Get only child Elements of this element.

This calls .children().iter().filter_map().collect(). Use Element::children() if performance is important.

Source

pub fn child_elements_recursive(&self, doc: &Document) -> Vec<Element>

Get child Elements recursively. (i.e. includes its child element’s child elements)

Source

pub fn find(&self, doc: &Document, name: &str) -> Option<Element>

Find first direct child element with name name.

Source

pub fn find_all(&self, doc: &Document, name: &str) -> Vec<Element>

Find all direct child elements with name name.

Source

pub fn find_quantified( &self, doc: &Document, name: &str, namespace_url: &str, ) -> Option<Element>

Find the first direct child element with the given tag name belonging to the specified namespace (identified by a namespace_url).

use biodivine_xml_doc::Document;

let mut doc = Document::parse_str(r#"<?xml version="1.0" encoding="UTF-8"?>
<parent xmlns:ns1="http://ns1" xmlns:ns2="http://ns2">
    <ns2:child id="1"/>
    <ns1:child id="2"/>
</parent>
"#).unwrap();

let root = doc.root_element().unwrap();
let child = root.find_quantified(&doc, "child", "http://ns1").unwrap();
assert_eq!(child.attribute(&doc, "id"), Some("2"));
Source

pub fn find_all_quantified( &self, doc: &Document, name: &str, namespace_url: &str, ) -> Vec<Element>

Find all the direct child elements with the given tag name belonging to the specified namespace (identified by a namespace_url).

use biodivine_xml_doc::Document;

let mut doc = Document::parse_str(r#"<?xml version="1.0" encoding="UTF-8"?>
<parent xmlns="http://ns1" xmlns:ns1="http://ns1" xmlns:ns2="http://ns2">
    <ns2:child id="1" />
    <child id="2" />
    <ns1:child id="3" />
</parent>
"#).unwrap();

let root = doc.root_element().unwrap();
let children = root.find_all_quantified(&doc, "child", "http://ns1");
assert_eq!(children.len(), 2);
assert_eq!(children[0].attribute(&doc, "id"), Some("2"));
assert_eq!(children[1].attribute(&doc, "id"), Some("3"));
Source

pub fn collect_namespace_prefixes<'a>( &self, doc: &'a Document, namespace_url: &str, ) -> HashSet<&'a str>

Compute all namespace prefixes that are valid for the given namespace_url in the context of this XML element.

The default prefix is represented as an empty string slice.

use biodivine_xml_doc::Document;

let mut doc = Document::parse_str(r#"<?xml version="1.0" encoding="UTF-8"?>
<parent xmlns="http://ns1" xmlns:ns1="http://ns1" xmlns:ns2="http://ns1">
    <child xmlns:ns2="http://ns2" />
</parent>
"#).unwrap();

let root = doc.root_element().unwrap();
let child = root.child_elements(&doc)[0];
// Three prefixes: `default`, `ns1`, and `ns2`
assert_eq!(root.collect_namespace_prefixes(&doc, "http://ns1").len(), 3);
// Only two prefixes. `ns2` is overridden.
assert_eq!(child.collect_namespace_prefixes(&doc, "http://ns1").len(), 2);
Source

pub fn collect_applicable_namespace_decls( &self, doc: &Document, ) -> HashMap<String, String>

Collect namespace declarations which apply to this XML Element.

The result contains the empty prefix only if it is declared with a non-empty namespace url.

use std::collections::HashMap;
use biodivine_xml_doc::Document;

let mut doc = Document::parse_str(r#"<?xml version="1.0" encoding="UTF-8"?>
<parent xmlns="http://ns1" xmlns:ns1="http://ns1" xmlns:ns2="http://ns1">
    <child xmlns:ns2="http://ns2">
        <ns1:child/>
        <ns2:child/>
    </child>
</parent>
"#).unwrap();

let root = doc.root_element().unwrap();
let child = root.child_elements(&doc)[0];
let declarations = child.collect_applicable_namespace_decls(&doc);
// The result should contain "" and "ns1". "ns2" is-redeclared on child, so is not needed.
let expected = HashMap::from([
    ("ns2".to_string(), "http://ns2".to_string()),
    ("ns1".to_string(), "http://ns1".to_string()),
    ("".to_string(), "http://ns1".to_string())
]);
assert_eq!(declarations.len(), 3);
assert_eq!(declarations, expected);
Source

pub fn collect_external_namespace_decls( &self, doc: &Document, ) -> HashMap<String, String>

Collect “parent” namespace declarations which apply to the XML sub-tree of this Element.

“Parent” declarations are those which appear on one of the parent tags of Element, not in the Element sub-tree. Each namespace prefix resolves to a specific URL based on standard XML namespace shadowing rules.

Note that the method can return a combination of an empty prefix and an empty url when the sub-tree contains elements with no prefix and there is no default namespace url declared by the parents.

use std::collections::HashMap;
use biodivine_xml_doc::Document;

let mut doc = Document::parse_str(r#"<?xml version="1.0" encoding="UTF-8"?>
<parent xmlns="http://ns1" xmlns:ns1="http://ns1" xmlns:ns2="http://ns1">
    <child xmlns:ns2="http://ns2">
        <ns1:child/>
        <ns2:child/>
    </child>
</parent>
"#).unwrap();

let root = doc.root_element().unwrap();
let child = root.child_elements(&doc)[0];
let declarations = child.collect_external_namespace_decls(&doc);
// The result should contain "" and "ns1". "ns2" is-redeclared on child, so is not needed.
let expected = HashMap::from([
    ("".to_string(), "http://ns1".to_string()),
    ("ns1".to_string(), "http://ns1".to_string())
]);
assert_eq!(declarations.len(), 2);
assert_eq!(declarations, expected);
Source

pub fn closest_prefix<'a>( &self, doc: &'a Document, namespace_url: &str, ) -> Option<&'a str>

Find the “closest” namespace prefix which is associated with the given namespace_url.

If the namespace is declared on the element itself, then its prefix is returned. Otherwise, the closest parent with the declared namespace is found and this prefix is returned. If the namespace is not declared for this element, None is returned.

If the “closest” element has multiple declarations of the namespace in question, the lexicographically first prefix is return (i.e. compared through standard string ordering).

You can use empty namespace url to signify “no namespace”, in which case the method can only return an empty prefix, but it can also return None if there is a default namespace which prevents you from having “no namespace” on this element.

use biodivine_xml_doc::Document;

let mut doc = Document::parse_str(r#"<?xml version="1.0" encoding="UTF-8"?>
<parent xmlns="http://ns1" xmlns:ns1="http://ns1" xmlns:ns2="http://ns2">
    <child xmlns:ns="http://ns2" />
</parent>
"#).unwrap();

let root = doc.root_element().unwrap();
let child = root.child_elements(&doc)[0];
assert_eq!(root.closest_prefix(&doc, "http://ns1"), Some(""));
assert_eq!(root.closest_prefix(&doc, "http://ns2"), Some("ns2"));
assert_eq!(child.closest_prefix(&doc, "http://ns1"), Some(""));
assert_eq!(child.closest_prefix(&doc, "http://ns2"), Some("ns"));
Source§

impl Element

Below are functions that modify its tree-structure.

Because an element has reference to both its parent and its children, an element’s parent and children is not directly exposed for modification. But in return, it is not possible for a document to be in an inconsistant state, where an element’s parent doesn’t have the element as its children.

Source

pub fn push_child(&self, doc: &mut Document, node: Node) -> Result<()>

Equivalent to vec.push().

§Errors
  • Error::HasAParent: When you want to replace an element’s parent with another, call element.detatch() to make it parentless first. This is to make it explicit that you are changing an element’s parent, not adding another.
  • Error::ContainerCannotMove: The container element’s parent must always be None.
Source

pub fn push_to(&self, doc: &mut Document, parent: Element) -> Result<()>

Equivalent to parent.push_child().

§Errors
  • Error::HasAParent: When you want to replace an element’s parent with another, call element.detatch() to make it parentless first. This is to make it explicit that you are changing an element’s parent, not adding another.
  • Error::ContainerCannotMove: The container element’s parent must always be None.
Source

pub fn insert_child( &self, doc: &mut Document, index: usize, node: Node, ) -> Result<()>

Equivalent to vec.insert().

§Panics

Panics if index > self.children().len()

§Errors
  • Error::HasAParent: When you want to replace an element’s parent with another, call element.detatch() to make it parentless first. This is to make it explicit that you are changing an element’s parent, not adding another.
  • Error::ContainerCannotMove: The container element’s parent must always be None.
Source

pub fn remove_child(&self, doc: &mut Document, index: usize) -> Node

Equivalent to vec.remove().

§Panics

Panics if index >= self.children().len().

Source

pub fn pop_child(&self, doc: &mut Document) -> Option<Node>

Equivalent to vec.pop().

Source

pub fn clear_children(&self, doc: &mut Document) -> Vec<Node>

Remove all children and return them.

Source

pub fn detatch(&self, doc: &mut Document) -> Result<()>

Removes itself from its parent. Note that you can’t attach this element to other documents.

§Errors

Trait Implementations§

Source§

impl Clone for Element

Source§

fn clone(&self) -> Element

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Element

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Hash for Element

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Element

Source§

fn eq(&self, other: &Element) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for Element

Source§

impl Eq for Element

Source§

impl StructuralPartialEq for Element

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.