5#include "Stroika/Foundation/Streams/MemoryStream.h"
7namespace Stroika::Foundation::DataExchange::XML::DOM {
14 template <Characters::IConvertibleToString ST>
15 inline XPath::Expression::Expression (ST&& e,
const Options& o)
16 : Expression{String{e}, o}
19 inline String XPath::Expression::GetExpression ()
const
21 return fRep_->GetExpression ();
23 inline auto XPath::Expression::GetOptions () const -> Options
25 return fRep_->GetOptions ();
27 inline auto XPath::Expression::GetRep () const -> shared_ptr<const IRep>
37 inline Node::Ptr::Ptr (
const shared_ptr<IRep>& from)
41 inline Node::Ptr::Ptr (nullptr_t)
47 if (fRep_ ==
nullptr) [[unlikely]] {
48 return rhs.fRep_ ==
nullptr;
50 if (rhs.fRep_ ==
nullptr) {
53 return fRep_->Equals (rhs.fRep_.get ());
57 return fRep_ ==
nullptr;
59 inline Node::Ptr::operator bool ()
const
61 return fRep_.operator bool ();
63 inline Node::Type Node::Ptr::GetNodeType ()
const
66 return fRep_->GetNodeType ();
70 Require (GetNodeType () == eAttributeNT or GetNodeType () == eElementNT);
71 return GetRep ()->GetName ();
75 Require (GetNodeType () == eAttributeNT or GetNodeType () == eElementNT);
76 GetRep ()->SetName (name);
80 Require (GetNodeType () == eAttributeNT or GetNodeType () == eElementNT);
81 return GetRep ()->GetValue ();
85 Require (GetNodeType () == eAttributeNT or GetNodeType () == eElementNT);
86 return GetRep ()->SetValue (v);
97 return fRep_->GetParentNode ();
119 : Node::Ptr{p != nullptr and p.GetNodeType () == Node::eElementNT ? p : nullptr}
121 Require (
PeekRep () ==
nullptr or GetNodeType () == eElementNT);
126 Require (
PeekRep () ==
nullptr or GetNodeType () == eElementNT);
129 : Node::Ptr{get<Node::Ptr> (r)}
131 Require (
PeekRep () ==
nullptr or GetNodeType () == eElementNT);
135 return GetRep ()->GetAttribute (attrName);
139 return GetRep ()->GetAttribute (attrName) != nullopt;
143 if (
auto o = GetRep ()->GetAttribute (attrName)) {
150 GetRep ()->SetAttribute (attrName, v);
152 template <same_as<VariantValue> VV>
155 GetRep ()->SetAttribute (attrName, v ==
nullptr ? optional<String>{} : v.template As<String> ());
159 static const NameWithNamespace kID_{
"id"sv};
160 return GetRep ()->GetAttribute (kID_);
164 if (
auto v = GetAttribute (kXMLNS)) {
171 SetAttribute (kXMLNS, defaultNS == nullopt ? optional<String>{} : defaultNS->As<
String> ());
175 Require (e.
GetOptions ().fResultTypeIndex == XPath::ResultTypeIndex_v<Node::Ptr>);
176 if (optional<XPath::Result> o = GetRep ()->LookupOne (e)) {
186 Require (e.
GetOptions ().fResultTypeIndex == XPath::ResultTypeIndex_v<Node::Ptr>);
187 return GetRep ()->Lookup (e).Map<
Iterable<String>> ([] (
const XPath::Result& e) -> optional<String> {
189 switch (ep.GetNodeType ()) {
190 case Node::Type::eAttributeNT:
191 case Node::Type::eElementNT:
200 Require (e.
GetOptions ().fResultTypeIndex == XPath::ResultTypeIndex_v<Node::Ptr>);
201 if (optional<XPath::Result> o = GetRep ()->LookupOne (e)) {
211 template <same_as<VariantValue> VV>
212 inline void Element::Ptr::SetValue (
const VV& v)
214 SetValue (v.template As<String> ());
216 template <same_as<VariantValue> VV>
217 inline void Element::Ptr::SetValue (
const XPath::Expression& e,
const VV& v)
219 SetValue (e, v.template As<String> ());
223 return GetRep ()->InsertElement (eltName, afterNode);
227 return GetRep ()->AppendElement (eltName);
231 auto r = Append (eltName);
235 template <same_as<VariantValue> VV>
238 auto r = Append (eltName);
239 r.SetValue (v.template As<String> ());
245 auto r = Append (eltName);
251 template <same_as<VariantValue> VV>
255 return Append (eltName, v.template As<String> ());
274 if (parent ==
nullptr) {
277 newNode = parent.Append (newEltName);
280 newNode = parent.Insert (newEltName, *
this);
283 Ensure (newNode.GetParent () == parent);
294 return GetRep ()->GetChildren ();
301 return eltNode ==
nullptr ? optional<Ptr>{} : eltNode;
306 return Element::Ptr{GetRep ()->GetChildElementByID (
id)};
314 Require (e.
GetOptions ().fResultTypeIndex == XPath::ResultTypeIndex_v<Node::Ptr>);
315 if (optional<XPath::Result> o = GetRep ()->LookupOne (e)) {
316 return get<Node::Ptr> (*o);
322 return GetRep ()->Lookup (e);
328 return ep !=
nullptr ? ep : optional<Element::Ptr>{};
347 inline Document::Ptr::Ptr (nullptr_t)
351 inline Document::Ptr::Ptr (
const shared_ptr<IRep>& rep)
360 inline bool Document::Ptr::operator== (nullptr_t)
const
362 return fRep_ ==
nullptr;
364 inline bool Document::Ptr::GetStandalone ()
const
366 return GetRep ()->GetStandalone ();
368 inline void Document::Ptr::SetStandalone (
bool standalone)
370 GetRep ()->SetStandalone (standalone);
374 GetRep ()->Write (to, options);
376 inline String Document::Ptr::Write (
const SerializationOptions& options)
const
380 GetRep ()->Write (bufferedOutput, options);
385 return GetRep ()->GetChildren ();
390 for (
Node::Ptr ni : GetRep ()->GetChildren ()) {
391 if (ni.GetNodeType () == Node::eElementNT) {
400 return GetRep ()->ReplaceRootElement (newEltName, childrenInheritNS);
405 return GetRootElement ().LookupOneElement (e);
410 return GetRootElement ().Lookup (e);
415 return GetRootElement ().LookupElements (e);
#define RequireNotNull(p)
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual Element::Ptr ReplaceRootElement(const NameWithNamespace &newEltName, bool childrenInheritNS=true) const
nonvirtual Iterable< Node::Ptr > GetChildren() const
nonvirtual Traversal::Iterable< Element::Ptr > LookupElements(const XPath::Expression &e) const
shorthand for GetRootElement ().LookupElements (e) - so requires root element exists
nonvirtual shared_ptr< IRep > GetRep() const
nonvirtual Element::Ptr GetRootElement() const
always returns Node of eElement or return nullptr if none
nonvirtual Element::Ptr LookupOneElement(const XPath::Expression &e) const
shorthand for GetRootElement ().LookupOneElement (e) - so requires root element exists
nonvirtual Traversal::Iterable< XPath::Result > Lookup(const XPath::Expression &e) const
shorthand for GetRootElement ().Lookup (e) - so requires root element exists
nonvirtual Ptr GetParent() const
nonvirtual Node::Ptr LookupOneNode(const XPath::Expression &e) const
nonvirtual shared_ptr< IRep > PeekRep() const
return the associated shared_ptr (can be nullptr)
nonvirtual optional< String > GetID() const
nonvirtual optional< URI > GetDefaultNamespace() const
nonvirtual Traversal::Iterable< Element::Ptr > LookupElements(const XPath::Expression &e) const
nonvirtual Ptr GetChildByID(const String &id) const
nonvirtual Ptr Append(const NameWithNamespace &eltName)
nonvirtual Element::Ptr LookupOneElement(const XPath::Expression &e) const
nonvirtual Ptr Replace(const NameWithNamespace &newEltName)
nonvirtual Traversal::Iterable< XPath::Result > Lookup(const XPath::Expression &e) const
nonvirtual Ptr AppendIf(const NameWithNamespace &eltName, const optional< String > &v)
Trivial wrapper on AppendElement, but if v is missing then this is a no-op.
nonvirtual void SetDefaultNamespace(const optional< URI > defaultNS=nullopt)
Sets the xmlns attribute of this element.
nonvirtual void SetAttribute(const NameWithNamespace &attrName, const optional< String > &v)
nonvirtual optional< String > GetAttribute(const NameWithNamespace &attrName) const
nonvirtual Iterable< Ptr > GetChildElements() const
nonvirtual Ptr Insert(const NameWithNamespace &eltName, const Node::Ptr &afterNode)
Insert Element (after argument node) inside of this 'Element'.
nonvirtual shared_ptr< IRep > GetRep() const
return the associated shared_ptr (cannot be nullptr)
nonvirtual Traversal::Iterable< String > GetValues(const XPath::Expression &e) const
nonvirtual Iterable< Node::Ptr > GetChildNodes() const
nonvirtual bool HasAttribute(const NameWithNamespace &attrName) const
Node::Ptr is a smart pointer to a Node::IRep.
nonvirtual Ptr GetParentNode() const
nonvirtual void SetValue(const String &v)
nonvirtual NameWithNamespace GetName() const
nonvirtual void SetName(const NameWithNamespace &name)
nonvirtual bool operator==(const Ptr &rhs) const
nonvirtual shared_ptr< IRep > PeekRep() const
return the associated shared_ptr (can be nullptr)
nonvirtual String GetValue() const
nonvirtual shared_ptr< IRep > GetRep() const
return the associated shared_ptr (cannot be nullptr)
nonvirtual Options GetOptions() const
OutputStream<>::Ptr is Smart pointer to a stream-based sink of data.
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
nonvirtual RESULT_CONTAINER Map(ELEMENT_MAPPER &&elementMapper) const
functional API which iterates over all members of an Iterable, applies a map function to each element...
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
Ptr New(const InputStream::Ptr< byte > &src, optional< AutomaticCodeCvtFlags > codeCvtFlags={}, optional< SeekableFlag > seekable={}, ReadAhead readAhead=eReadAheadAllowed)
Create an InputStream::Ptr<Character> from the arguments (usually binary source) - which can be used ...