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
impl Element
Sourcepub fn new<S: Into<String>>(doc: &mut Document, full_name: S) -> Self
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.
Sourcepub fn build<S: Into<String>>(name: S) -> ElementBuilder
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();Sourcepub fn is_container(&self) -> bool
pub fn is_container(&self) -> bool
Returns true if element is a container.
See Document::container() for more information on ‘container’.
Sourcepub fn separate_prefix_name(full_name: &str) -> (&str, &str)
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.
impl Element
Below are methods that take &Document as its first argument.
Sourcepub fn is_root(&self, doc: &Document) -> bool
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.
Sourcepub fn top_parent(&self, doc: &Document) -> Element
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.
Sourcepub fn full_name<'a>(&self, doc: &'a Document) -> &'a str
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.
pub fn set_full_name<S: Into<String>>(&self, doc: &mut Document, name: S)
Sourcepub fn prefix_name<'a>(&self, doc: &'a Document) -> (&'a str, &'a str)
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")
Sourcepub fn prefix<'a>(&self, doc: &'a Document) -> &'a str
pub fn prefix<'a>(&self, doc: &'a Document) -> &'a str
Get namespace prefix of element, without name.
<prefix:name> -> "prefix"
Sourcepub fn set_prefix<S: Into<String>>(&self, doc: &mut Document, prefix: S)
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.
Sourcepub fn name<'a>(&self, doc: &'a Document) -> &'a str
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"
Sourcepub fn set_name<S: Into<String>>(&self, doc: &mut Document, name: S)
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.
Sourcepub fn attributes<'a>(&self, doc: &'a Document) -> &'a HashMap<String, String>
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")
}Sourcepub fn attribute<'a>(&self, doc: &'a Document, name: &str) -> Option<&'a str>
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)
Sourcepub fn set_attribute<S, T>(&self, doc: &mut Document, name: S, value: T)
pub fn set_attribute<S, T>(&self, doc: &mut Document, name: S, value: T)
Add or set attribute.
If name contains a :,
everything before : will be interpreted as namespace prefix.
pub fn mut_attributes<'a>( &self, doc: &'a mut Document, ) -> &'a mut HashMap<String, String>
Sourcepub fn namespace<'a>(&self, doc: &'a Document) -> Option<&'a str>
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)).
Sourcepub fn namespace_decls<'a>(
&self,
doc: &'a Document,
) -> &'a HashMap<String, String>
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.
pub fn mut_namespace_decls<'a>( &self, doc: &'a mut Document, ) -> &'a mut HashMap<String, String>
pub fn set_namespace_decl<S, T>( &self, doc: &mut Document, prefix: S, namespace: T, )
Sourcepub fn namespace_for_prefix<'a>(
&self,
doc: &'a Document,
prefix: &str,
) -> Option<&'a str>
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.
Sourcepub fn is_quantified(&self, doc: &Document, namespace_url: &str) -> bool
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.
Sourcepub fn quantify_with_closest(
&self,
doc: &mut Document,
namespace_url: &str,
) -> Option<String>
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"));Sourcepub fn text_content(&self, doc: &Document) -> String
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
Sourcepub fn set_text_content<S: Into<String>>(&self, doc: &mut Document, text: S)
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.
impl Element
Below are methods related to finding nodes in tree.
pub fn parent(&self, doc: &Document) -> Option<Element>
Sourcepub fn has_parent(&self, doc: &Document) -> bool
pub fn has_parent(&self, doc: &Document) -> bool
self.parent(doc).is_some()
Sourcepub fn children<'a>(&self, doc: &'a Document) -> &'a Vec<Node>
pub fn children<'a>(&self, doc: &'a Document) -> &'a Vec<Node>
Get child Nodes of this element.
Sourcepub fn children_recursive<'a>(&self, doc: &'a Document) -> Vec<&'a Node>
pub fn children_recursive<'a>(&self, doc: &'a Document) -> Vec<&'a Node>
Get all child nodes recursively. (i.e. includes its children’s children.)
Sourcepub fn has_children(&self, doc: &Document) -> bool
pub fn has_children(&self, doc: &Document) -> bool
!self.children(doc).is_empty()
Sourcepub fn child_elements(&self, doc: &Document) -> Vec<Element>
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.
Sourcepub fn child_elements_recursive(&self, doc: &Document) -> Vec<Element>
pub fn child_elements_recursive(&self, doc: &Document) -> Vec<Element>
Get child Elements recursively. (i.e. includes its child element’s child elements)
Sourcepub fn find(&self, doc: &Document, name: &str) -> Option<Element>
pub fn find(&self, doc: &Document, name: &str) -> Option<Element>
Find first direct child element with name name.
Sourcepub fn find_all(&self, doc: &Document, name: &str) -> Vec<Element>
pub fn find_all(&self, doc: &Document, name: &str) -> Vec<Element>
Find all direct child elements with name name.
Sourcepub fn find_quantified(
&self,
doc: &Document,
name: &str,
namespace_url: &str,
) -> Option<Element>
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"));Sourcepub fn find_all_quantified(
&self,
doc: &Document,
name: &str,
namespace_url: &str,
) -> Vec<Element>
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"));Sourcepub fn collect_namespace_prefixes<'a>(
&self,
doc: &'a Document,
namespace_url: &str,
) -> HashSet<&'a str>
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);Sourcepub fn collect_applicable_namespace_decls(
&self,
doc: &Document,
) -> HashMap<String, String>
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);Sourcepub fn collect_external_namespace_decls(
&self,
doc: &Document,
) -> HashMap<String, String>
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);Sourcepub fn closest_prefix<'a>(
&self,
doc: &'a Document,
namespace_url: &str,
) -> Option<&'a str>
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.
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.
Sourcepub fn push_child(&self, doc: &mut Document, node: Node) -> Result<()>
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, callelement.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.
Sourcepub fn push_to(&self, doc: &mut Document, parent: Element) -> Result<()>
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, callelement.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.
Sourcepub fn insert_child(
&self,
doc: &mut Document,
index: usize,
node: Node,
) -> Result<()>
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, callelement.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.
Sourcepub fn remove_child(&self, doc: &mut Document, index: usize) -> Node
pub fn remove_child(&self, doc: &mut Document, index: usize) -> Node
Sourcepub fn clear_children(&self, doc: &mut Document) -> Vec<Node>
pub fn clear_children(&self, doc: &mut Document) -> Vec<Node>
Remove all children and return them.