TSDuck v3.46-4930
MPEG Transport Stream Toolkit
Loading...
Searching...
No Matches
ts::xml::JSONConverter Class Reference

#include <tsxmlJSONConverter.h>

Inheritance diagram for ts::xml::JSONConverter:
Collaboration diagram for ts::xml::JSONConverter:

Public Member Functions

 JSONConverter (Report &report=(ts::NullReport::Instance()))
virtual ~JSONConverter () override
size_t childrenCount () const
virtual void clear ()
virtual Node * clone () const override
json::ValuePtr convertToJSON (const Document &source, bool force_root=false) const
bool convertToXML (const json::Value &source, Document &destination, bool auto_validate) const
UString debug () const
size_t depth () const
Document * document ()
const Document * document () const
virtual void expandEnvironment (bool recurse)
Node * firstChild ()
const Node * firstChild () const
Element * firstChildElement ()
const Element * firstChildElement () const
bool hasChildren () const
bool ignoreNamespace () const
Element * initialize (const UString &rootName, const UString &declaration=UString())
Node * lastChild ()
const Node * lastChild () const
size_t lineNumber () const
bool load (const UString &file_name, bool search=true, size_t max_nested=DEFAULT_MAX_NESTED)
bool load (std::istream &strm, size_t max_nested=DEFAULT_MAX_NESTED)
void move (Node *new_sibling, bool before)
void moveAfter (Node *new_sibling)
void moveBefore (Node *new_sibling)
Node * nextSibling ()
const Node * nextSibling () const
Element * nextSiblingElement ()
const Element * nextSiblingElement () const
virtual UString oneLiner () const
Node * parent ()
const Node * parent () const
bool parse (const UString &text, size_t max_nested=DEFAULT_MAX_NESTED)
bool parse (const UStringList &lines, size_t max_nested=DEFAULT_MAX_NESTED)
bool preserveSpace () const
Node * previousSibling ()
const Node * previousSibling () const
Element * previousSiblingElement ()
const Element * previousSiblingElement () const
virtual void print (TextFormatter &output, bool keep_node_open=false) const override
virtual void printClose (TextFormatter &output, size_t levels=std::numeric_limits< size_t >::max()) const override
void removeComments (bool recurse)
void reparent (Node *new_parent, bool last=true)
Report & report () const
bool ringAlone () const
void ringInsertAfter (RingNode *o)
void ringInsertBefore (RingNode *o)
template<typename T>
T * ringNext ()
template<typename T>
const T * ringNext () const
template<typename T>
T * ringPrevious ()
template<typename T>
const T * ringPrevious () const
void ringRemove ()
size_t ringSize () const
void ringSwap (RingNode *o)
Element * rootElement ()
const Element * rootElement () const
bool save (const fs::path &file_name, size_t indent=2)
virtual void setIignoreNamespace (bool ignore)
void setTweaks (const Tweaks &tw)
void setValue (const UString &value)
virtual bool stickyOutput () const
virtual UString toString () const override
virtual const Tweaks & tweaks () const override
virtual UString typeName () const override
bool validate (const Document &doc) const
const UString & value () const

Static Public Member Functions

static UString DisplayFileName (const UString &name, bool stdInputIfEmpty=false)
static bool IsInlineXML (const UString &name)

Static Public Attributes

static const UString HashName
static const UString HashNodes
static const UString HashUnnamed

Protected Member Functions

const Element * findModelElement (const Element *elem, const UString &name) const
Node * identifyNextNode (TextParser &parser)
virtual bool parseChildren (TextParser &parser, size_t max_nested)
virtual bool parseNode (TextParser &parser, const Node *parent, size_t max_nested) override
void setPreserveSpace (bool on)

Detailed Description

XML-to-JSON converter.

An XML-to-JSON converter is a model document which is used to convert an XML document into a JSON object.

In this class, the XML model is not used to validate the XML document. The model is optional (it can be empty). It is only used as a hint to infer the type of XML attributes and text nodes in the source document.

There is no standard way to convert XML to JSON. Several tools exist and each of them has its own conversion rules. Here, we use the following rules:

  • Each XML element is converted to a JSON object {...}.
  • The name of the XML element is an attribute "#name" inside the object. Note that it was not possible to transform '<foo .../>' into '"foo" : {...}' because several XML element with the same name can appear in the same block. Consequently, '<foo .../>' is converted to '{"#name" : "foo", ...}'.
  • All attributes of the XML element are directly mapped into the JSON object.
    • By default, attribute values are converted to JSON strings.
    • If the model has a value for this attribute and if this model value starts with "int" or "uint" and the attribute value can be successfully converted to an integer, then the value becomes a JSON number.
    • Similarly, if the model value starts with "bool" and the value can be successfully converted to a boolean, then the value becomes a JSON True or False.
  • The children nodes inside an element are placed in a JSON array with name "#nodes". Consequently, '<foo> <bar/> <baz/> </foo>' is converted to '{"#name" : "foo", "#nodes" : [{"#name" : "bar"}, {"#name" : "baz"}]}'.
  • Each XML text node is converted to a JSON string. If the model has a value for this text node and if this model value starts with "hexa", then all spaces are collapsed inside the string.
  • XML declarations, comments and "unknown" nodes are dropped.

Constructor & Destructor Documentation

◆ JSONConverter()

ts::xml::JSONConverter::JSONConverter ( Report & report = (ts::NullReport::Instance()))

Default constructor.

Parameters
[in,out]reportWhere to report errors.

◆ ~JSONConverter()

virtual ts::xml::JSONConverter::~JSONConverter ( )
overridevirtual

Destructor.

Member Function Documentation

◆ convertToJSON()

json::ValuePtr ts::xml::JSONConverter::convertToJSON ( const Document & source,
bool force_root = false ) const

Convert an XML document into a JSON object.

Parameters
[in]sourceThe source XML document to convert.
[in]force_rootIf true, force the option --x2j-include-root.
Returns
A safe pointer to the converted JSON object. Never null. Point to a JSON Null on error.

◆ convertToXML()

bool ts::xml::JSONConverter::convertToXML ( const json::Value & source,
Document & destination,
bool auto_validate ) const

Convert a JSON object into an XML document. Not all JSON values can be converted. Basically, only JSON objects which were previously converted from XML are guaranteed to be converted back. For other values, a best-effort conversion is applied, without guarantee.

Parameters
[in]sourceThe source JSON value to convert. If this is a JSON object, it becomes the root of the XML document. If this is an array, the XML root is taken from the model and the array elements are converted inside that root.
[out]destinationThe converted XML document.
[in]auto_validateIf true, the converted document is validated according to the modeL.
Returns
True if the JSON source is converted without error and is correctly validated.

◆ validate()

bool ts::xml::ModelDocument::validate ( const Document & doc) const
inherited

Validate an XML document.

Parameters
[in]docThe document to validate according to the model.
Returns
True if doc matches the model in this object, false if it does not.

◆ clone()

virtual Node * ts::xml::ModelDocument::clone ( ) const
overridevirtualinherited

Clone the content of the node in a dynamically allocated object. This virtual method must be implemented by subclasses to allocate a object of the right class.

Returns
The address of a new XML node of the same class as this object, same content, same structure.

Reimplemented from ts::xml::Document.

◆ findModelElement()

const Element * ts::xml::ModelDocument::findModelElement ( const Element * elem,
const UString & name ) const
inlineprotectedinherited

Find a child element by name in an XML model element.

Parameters
[in]elemAn XML element in a model document.
[in]nameName of the child element to search.
Returns
Address of the child model or zero if not found.

◆ parse() [1/2]

bool ts::xml::Document::parse ( const UStringList & lines,
size_t max_nested = DEFAULT_MAX_NESTED )
inherited

Parse an XML document.

Parameters
[in]linesList of text lines forming the XML document.
[in]max_nestedMaximum number of nested levels to parse. The default value is recommended to avoid stack overflow.
Returns
True on success, false on error.

◆ parse() [2/2]

bool ts::xml::Document::parse ( const UString & text,
size_t max_nested = DEFAULT_MAX_NESTED )
inherited

Parse an XML document.

Parameters
[in]textThe XML document.
[in]max_nestedMaximum number of nested levels to parse. The default value is recommended to avoid stack overflow.
Returns
True on success, false on error.

◆ load() [1/2]

bool ts::xml::Document::load ( const UString & file_name,
bool search = true,
size_t max_nested = DEFAULT_MAX_NESTED )
inherited

Load and parse an XML file.

Parameters
[in]file_nameName of the XML file to load. If file_name is empty or "-", read the standard input. If file_name starts with "<?xml", this is considered as "inline XML content". The document is loaded from this string instead of reading a file.
[in]searchIf true, search the XML file in the TSDuck configuration directories if file_name is not found and does not contain any directory part.
[in]max_nestedMaximum number of nested levels to parse. The default value is recommended to avoid stack overflow.
Returns
True on success, false on error.
See also
SearchConfigurationFile()

◆ load() [2/2]

bool ts::xml::Document::load ( std::istream & strm,
size_t max_nested = DEFAULT_MAX_NESTED )
inherited

Load and parse an XML file.

Parameters
[in,out]strmA standard text stream in input mode.
[in]max_nestedMaximum number of nested levels to parse. The default value is recommended to avoid stack overflow.
Returns
True on success, false on error.

◆ save()

bool ts::xml::Document::save ( const fs::path & file_name,
size_t indent = 2 )
inherited

Save an XML file.

Parameters
[in]file_nameName of the XML file to save. If file_name is empty or "-", writes to the standard output.
[in]indentIndentation width of each level.
Returns
True on success, false on error.

◆ IsInlineXML()

bool ts::xml::Document::IsInlineXML ( const UString & name)
staticinherited

Check if a "file name" is in fact inline XML content instead of a file name.

Parameters
[in]nameA file name string.
Returns
True if name contains inline XML content, false otherwise.

◆ DisplayFileName()

UString ts::xml::Document::DisplayFileName ( const UString & name,
bool stdInputIfEmpty = false )
staticinherited

Get a suitable display name for an XML file name or inline content.

Parameters
[in]nameA file name string.
[in]stdInputIfEmptyIf true and if file_name is empty, reads the standard input.
Returns
A suitable string to display.

◆ rootElement() [1/2]

const Element * ts::xml::Document::rootElement ( ) const
inlineinherited

Get the root element of the document.

Returns
The root element of the document or a null pointer if there is none.

◆ rootElement() [2/2]

Element * ts::xml::Document::rootElement ( )
inlineinherited

Get the root element of the document.

Returns
The root element of the document or or a null pointer if there is none.

◆ initialize()

Element * ts::xml::Document::initialize ( const UString & rootName,
const UString & declaration = UString() )
inherited

Initialize the document. The initial declaration and root are created.

Parameters
[in]rootNameName of the root element to create.
[in]declarationOptional XML declaration. When omitted, the standard declaration is used, specifying UTF-8 as format.
Returns
New root element of the document or null on error.

◆ tweaks()

virtual const Tweaks & ts::xml::Document::tweaks ( ) const
overridevirtualinherited

Get a constant reference to the global XML parsing and formatting tweaks for the document.

Returns
A constant reference to the global XML tweaks.

Reimplemented from ts::xml::Node.

◆ setTweaks()

void ts::xml::Document::setTweaks ( const Tweaks & tw)
inlineinherited

Set the global XML parsing and formatting tweaks for the document.

Parameters
[in]twThe new global XML tweaks.

◆ toString()

virtual UString ts::xml::Document::toString ( ) const
overridevirtualinherited

Convert to a string object.

Returns
This object, converted as a string.

Implements ts::StringifyInterface.

◆ typeName()

virtual UString ts::xml::Document::typeName ( ) const
overridevirtualinherited

Return a node type name, mainly for debug purpose.

Returns
Node type name.

Implements ts::xml::Node.

◆ print()

virtual void ts::xml::Document::print ( TextFormatter & output,
bool keep_node_open = false ) const
overridevirtualinherited

Format the node for an output XML document.

Parameters
[in,out]outputThe output object to format the XML document.
[in]keep_node_openIf true, keep the node open so that children may be printed later.

Implements ts::xml::Node.

◆ printClose()

virtual void ts::xml::Document::printClose ( TextFormatter & output,
size_t levels = std::numeric_limits< size_t >::max() ) const
overridevirtualinherited

Print the closing tags for the node. Typically used after print() when keep_node_open was true. The default implementation is to do nothing. Subclasses may replace this.

Parameters
[in,out]outputThe output object to format the XML document.
[in]levelsNumber of levels to close. By default, close the complete document. If zero, no output is produced.

Reimplemented from ts::xml::Node.

◆ parseNode()

virtual bool ts::xml::Document::parseNode ( TextParser & parser,
const Node * parent,
size_t max_nested )
overrideprotectedvirtualinherited

Parse the node.

Parameters
[in,out]parserThe document parser. On input, the current position of the parser after the tag which identified the node ("<?", "<!- -", etc.) On output, it must be after the last character of the node.
[in]parentCandidate parent node, for information only, do not modify. Can be null.
[in]max_nestedMaximum number of nested levels to explore.
Returns
True on success, false on error.

Implements ts::xml::Node.

◆ lineNumber()

size_t ts::xml::Node::lineNumber ( ) const
inlineinherited

Get the line number in input document.

Returns
The line number in input document, zero if the node was built programmatically.

◆ clear()

virtual void ts::xml::Node::clear ( )
virtualinherited

Clear the content of the node. The node becomes empty but remains attached to its parent.

Reimplemented in ts::xml::Element.

◆ reparent()

void ts::xml::Node::reparent ( Node * new_parent,
bool last = true )
inherited

Attach the node to a new parent. The node is first detached from its previous parent.

Parameters
[in,out]new_parentNew parent. If zero, the node becomes orphan. In that case, the node will no longer be freed by its parent and must be explicitly deleted.
[in]lastIf true, the child is added at the end of the list of children. If false, it is added at the beginning.

◆ moveBefore()

void ts::xml::Node::moveBefore ( Node * new_sibling)
inlineinherited

Move the node before another node, potentially to a new parent.

Parameters
[in,out]new_siblingA new sibling. The node will be moved before this one.

◆ moveAfter()

void ts::xml::Node::moveAfter ( Node * new_sibling)
inlineinherited

Move the node after another node, potentially to a new parent.

Parameters
[in,out]new_siblingA new sibling. The node will be moved after this one.

◆ move()

void ts::xml::Node::move ( Node * new_sibling,
bool before )
inherited

Move the node before or after another node, potentially to a new parent.

Parameters
[in,out]new_siblingA new sibling. The node will be moved before or after this one.
[in]beforeIf true, move the node before new_sibling, after it otherwise.

◆ parent() [1/2]

const Node * ts::xml::Node::parent ( ) const
inlineinherited

Get the parent's node.

Returns
The parent's node or a null pointer if this is a top-level document.

◆ parent() [2/2]

Node * ts::xml::Node::parent ( )
inlineinherited

Get the parent's node.

Returns
The parent's node or zero if this is a top-level document.

◆ document() [1/2]

const Document * ts::xml::Node::document ( ) const
inlineinherited

Get the document into which the node is located.

Returns
The node's document or zero if there is no document.

◆ document() [2/2]

Document * ts::xml::Node::document ( )
inherited

Get the document into which the node is located.

Returns
The node's document or zero if there is no document.

◆ depth()

size_t ts::xml::Node::depth ( ) const
inherited

Get the depth of an XML element.

Returns
The depth of the element, ie. the number of ancestors.

◆ preserveSpace()

bool ts::xml::Node::preserveSpace ( ) const
inherited

Check if the node or one of its ancestors has attribute xml:space="preserve".

Returns
True if spaces shall be preserved.

◆ ignoreNamespace()

bool ts::xml::Node::ignoreNamespace ( ) const
inlineinherited

Check if namespace is ignored by default when comparing element and attribute names in this node's hierarchy.

Returns
True if namespace is ignored by default.

◆ setIignoreNamespace()

virtual void ts::xml::Node::setIignoreNamespace ( bool ignore)
virtualinherited

Specify if namespace is ignored by default when comparing element and attribute names in this node's hierarchy.

Parameters
[in]ignoreIt true, namespace is ignored by default.

Reimplemented in ts::xml::Element.

◆ hasChildren()

bool ts::xml::Node::hasChildren ( ) const
inlineinherited

Check if the node has children.

Returns
True if the node has children.

◆ childrenCount()

size_t ts::xml::Node::childrenCount ( ) const
inlineinherited

Get the number of children.

Returns
The number of children.

◆ firstChild() [1/2]

const Node * ts::xml::Node::firstChild ( ) const
inlineinherited

Get the first child of a node.

Returns
The first child of the node or zero if there is no children.

◆ firstChild() [2/2]

Node * ts::xml::Node::firstChild ( )
inlineinherited

Get the first child of a node.

Returns
The first child of the node or zero if there is no children.

◆ lastChild() [1/2]

const Node * ts::xml::Node::lastChild ( ) const
inlineinherited

Get the last child.

Returns
The last child or zero if there is none.

◆ lastChild() [2/2]

Node * ts::xml::Node::lastChild ( )
inlineinherited

Get the last child.

Returns
The last child or nullptr if there is none.

◆ nextSibling() [1/2]

const Node * ts::xml::Node::nextSibling ( ) const
inlineinherited

Get the next sibling node.

Returns
The next sibling node or zero if the node is the last child.

◆ nextSibling() [2/2]

Node * ts::xml::Node::nextSibling ( )
inherited

Get the next sibling node.

Returns
The next sibling node or zero if the node is the last child.

◆ previousSibling() [1/2]

const Node * ts::xml::Node::previousSibling ( ) const
inlineinherited

Get the previous sibling node.

Returns
The previous sibling node or zero if the node is the first child.

◆ previousSibling() [2/2]

Node * ts::xml::Node::previousSibling ( )
inherited

Get the previous sibling node.

Returns
The previous sibling node or zero if the node is the first child.

◆ firstChildElement() [1/2]

const Element * ts::xml::Node::firstChildElement ( ) const
inlineinherited

Get the first child Element of a node.

Returns
The first child Element of the node or zero if there is no child Element.

◆ firstChildElement() [2/2]

Element * ts::xml::Node::firstChildElement ( )
inherited

Get the first child Element of a node.

Returns
The first child Element of the node or zero if there is no child Element.

◆ nextSiblingElement() [1/2]

const Element * ts::xml::Node::nextSiblingElement ( ) const
inlineinherited

Find the next sibling element.

Returns
Element address or zero if not found.

◆ nextSiblingElement() [2/2]

Element * ts::xml::Node::nextSiblingElement ( )
inherited

Find the next sibling element.

Returns
Element address or zero if not found.

◆ previousSiblingElement() [1/2]

const Element * ts::xml::Node::previousSiblingElement ( ) const
inlineinherited

Find the previous sibling element.

Returns
Element address or zero if not found.

◆ previousSiblingElement() [2/2]

Element * ts::xml::Node::previousSiblingElement ( )
inherited

Find the previous sibling element.

Returns
Element address or zero if not found.

◆ value()

const UString & ts::xml::Node::value ( ) const
inlineinherited

Get the value of the node.

The semantic of the value depends on the node subclass:

  • Comment: Content of the comment, without "<!--" and "-->".
  • Declaration: Content of the declaration, without "<?" and "?>".
  • Document: Empty.
  • Element: Name of the element.
  • Text: Text content of the element, including spaces and new-lines.
  • Unknown: Content of the tag, probably an uninterpreted DTD.
Returns
A constant reference to the node value, as a string.

◆ setValue()

void ts::xml::Node::setValue ( const UString & value)
inlineinherited

Set the value of the node.

Parameters
[in]valueNew value to set.
See also
value()

◆ removeComments()

void ts::xml::Node::removeComments ( bool recurse)
inherited

Remove all comments in the XML node.

Parameters
[in]recurseIf true, apply recursively to all children nodes.

◆ expandEnvironment()

virtual void ts::xml::Node::expandEnvironment ( bool recurse)
virtualinherited

Expand all environment variables in the XML node. Environment variables are referenced using '${varname}' in text, attributes, names.

Parameters
[in]recurseIf true, apply recursively to all children nodes.

Reimplemented in ts::xml::Element.

◆ oneLiner()

virtual UString ts::xml::Node::oneLiner ( ) const
virtualinherited

Format the value as a one-liner XML text.

Returns
The formatted one-line XML text.

◆ stickyOutput()

virtual bool ts::xml::Node::stickyOutput ( ) const
virtualinherited

Check if the text shall be stuck to other elements in XML output.

Returns
True if the text shall be stuck to other elements. False by default.

Reimplemented in ts::xml::Text.

◆ debug()

UString ts::xml::Node::debug ( ) const
inherited

Build a debug string for the node.

Returns
A debug string for the node.

◆ report()

Report & ts::xml::Node::report ( ) const
inlineinherited

Get a reference to the report object for the XML node.

Returns
A reference to the report object for the XML node.

◆ identifyNextNode()

Node * ts::xml::Node::identifyNextNode ( TextParser & parser)
protectedinherited

Identify the next token in the document.

Parameters
[in,out]parserThe document parser.
Returns
A new node or zero either at end of document or before a "</" sequence. The returned node, when not zero, is not yet linked to its parent and siblings. When the returned node is not zero, the parser is located after the tag which identified the node ("<?", "<!- -", etc.)

◆ parseChildren()

virtual bool ts::xml::Node::parseChildren ( TextParser & parser,
size_t max_nested )
protectedvirtualinherited

Parse children nodes and add them to the node. Stop either at end of document or before a "</" sequence or on error.

Parameters
[in,out]parserThe document parser.
[in]max_nestedMaximum number of nested levels to explore.
Returns
True on success, false on error.

◆ setPreserveSpace()

void ts::xml::Node::setPreserveSpace ( bool on)
inlineprotectedinherited

Called by the subclass when its spaces shall be preserved. Typically called when xml:space="preserve" is encountered.

Parameters
[in]onTrue is spaces shall be preserved.

◆ ringAlone()

bool ts::RingNode::ringAlone ( ) const
inlineinherited

Check if the node is alone in its own ring.

Returns
True if the node is alone in its own ring.

◆ ringRemove()

void ts::RingNode::ringRemove ( )
inherited

Remove the node from the ring it belongs to and creates its own ring.

◆ ringInsertAfter()

void ts::RingNode::ringInsertAfter ( RingNode * o)
inherited

Insert this object in a ring after the specified node.

Parameters
[in]oA node of a ring. This object is inserted after o in the ring.

◆ ringInsertBefore()

void ts::RingNode::ringInsertBefore ( RingNode * o)
inherited

Insert this object in a ring before the specified node.

Parameters
[in]oA node of a ring. This object is inserted before o in the ring.

◆ ringSwap()

void ts::RingNode::ringSwap ( RingNode * o)
inherited

Swap this object and another one in their rings. If the two objects belong to the same ring, their positions are swapped. If they belong to distinct rings, they also move to each other's ring.

Parameters
[in]oThe node to swap with.

◆ ringNext() [1/2]

template<typename T>
T * ts::RingNode::ringNext ( )
inlineinherited

Get the next node in the ring.

Template Parameters
TA superclass of RingNode, the expected type of the next object in the ring.
Returns
Address of the next node in the ring or zero if the next node is not a subclass of T.

◆ ringNext() [2/2]

template<typename T>
const T * ts::RingNode::ringNext ( ) const
inlineinherited

Get the next node in the ring.

Template Parameters
TA superclass of RingNode, the expected type of the next object in the ring.
Returns
Address of the next node in the ring or zero if the next node is not a subclass of T.

◆ ringPrevious() [1/2]

template<typename T>
T * ts::RingNode::ringPrevious ( )
inlineinherited

Get the previous node in the ring.

Template Parameters
TA superclass of RingNode, the expected type of the previous object in the ring.
Returns
Address of the previous node in the ring or zero if the previous node is not a subclass of T.

◆ ringPrevious() [2/2]

template<typename T>
const T * ts::RingNode::ringPrevious ( ) const
inlineinherited

Get the previous node in the ring.

Template Parameters
TA superclass of RingNode, the expected type of the previous object in the ring.
Returns
Address of the previous node in the ring or zero if the previous node is not a subclass of T.

◆ ringSize()

size_t ts::RingNode::ringSize ( ) const
inherited

Count the number of element in the ring. Warning: This method has a linear response time, avoid using it when possible.

Returns
The number of nodes in the ring.

Member Data Documentation

◆ HashName

const UString ts::xml::JSONConverter::HashName
static

The string "#name" which is used to hold the name of an XML element in a JSON object.

◆ HashNodes

const UString ts::xml::JSONConverter::HashNodes
static

The string "#nodes" which is used to hold the children of an XML element in a JSON object.

◆ HashUnnamed

const UString ts::xml::JSONConverter::HashUnnamed
static

The string "_unnamed" which is used for reverse JSON-toXML conversion for unnamed objects.


The documentation for this class was generated from the following file: