Last Updated: 6 Mar, 2021

XML encoding

Moderate
Asked in companies
UberFacebookApple

Problem statement

The eXtensible Markup Language (XML) is a simple text-based format for representing information. The syntax for XML is as follows:

  1. Element => TAG Attributes END Child END
  2. Attribute => TAG Value

  • Value: String value.
  • TAG: Default mapping to an integer value.
  • Child: List of ā€˜Elements’ or a single ā€˜Value’. Never both.
  • End: Encoded as 0.

You are given an ā€˜Element’ object and the mapping of each ā€˜TAG’ to an integer value. The task is to encode this ā€˜Element’ using the ā€˜TAG’ mapping and return the resultant string.

Example:
Element object:
<codingNinjas course=ā€œInterviewPreparationā€ type=ā€œIndividualCourseā€>
    <topic name=ā€œAptitudeā€>CourseContents</topic>
</codingNinjas>

Tag mapping:
ā€˜codingNinjas’ => 1, ā€˜topic’ => 2, ā€˜courseName’ => 3, ā€˜type’ => 4, ā€˜topicName’ => 5

The given element is ā€˜codingNinjas’, and it has a single child element ā€˜topic’. The element ā€˜codingNinjas’ has two attributes having tags as ā€˜course’ and ā€˜type’. The element ā€˜topic’ has one attribute with the tag as ā€˜name’. So, the encoded string is: 

ā€˜1 3 InterviewPreparation 4 IndividualCourse 0 2 5 Aptitude 0 CourseContents 0 0’
Note:
1. ā€˜END’ is always encoded as 0.
2. An ā€˜Element’ can have zero or multiple ā€˜Attributes’.
Function description:
The function ā€˜encodeXML’ has the following parameters:
Pointer to an ā€˜Element’ object.
Mapping of ā€˜TAG’ name (string) to an integer value.
Structure of ā€˜Element’ and ā€˜Attribute’ object:
Element {
    String tag;
    List<Attribute> attributes;
    List<Element *> child;
    String value;
}
Attribute {
    String tag;
    String value;
}

If ā€˜Element’ stores a list of child elements, then ā€˜(Element => values)’ stores an empty string.
Input format:
The first line of input contains an integer ā€˜T’ denoting the number of test cases.

The first line of each test case contains an integer ā€˜N’ denoting the count of elements, including nested elements.

The following ā€˜N’ blocks of lines contain the description of ā€˜N’ elements. Each block is as follows:

 1. Each block’s first line contains three space-separated values, integer ā€˜ID’ denoting the element’s id, ā€˜M’ denoting the number of ā€˜Attributes’, and a string denoting the element’s ā€˜tag’. The ā€˜ID’ is used later on to identify the child elements.
 2. The next ā€˜M’ lines contain two space-separated integers denoting the ā€˜tag’ and ā€˜value’ of each ā€˜Attribute’.
 3. The next line contains either of the following:
     a. If the element stores a value, it contains the integer 0 and a string denoting the ā€˜value’ in the element, separated by space.
     b. Otherwise, an integer ā€˜C’ denoting the number of child elements.

The next ā€˜N - 1’ lines contain two space-separated integers, ā€˜A’ and ā€˜B’, the element with ā€˜id’ as ā€˜B’ is the child of the element with ā€˜id’ as ā€˜A’. The given ā€˜Element’ object always has ā€˜id’ equal to ā€˜1’ and has no parent.

The next line of each test case contains an integer ā€˜S’ denoting the number of ā€˜tags’.

The next ā€˜S’ lines of each test case contain two space-separated values, a string denoting the ā€˜tag’ name and an integer mapped to this ā€˜tag’.
Output format:
For each test case, return the encoded string.
Note:
You do not need to print anything; it has already been taken care of. Just implement the function.
Constraints:
1 <= T <= 10
2 <= N <= 1000

The count of ā€˜Attributes’ of all elements doesn’t exceed 1000.
The string ā€˜Value’ is non-empty and contains only ā€˜a-z’ and ā€˜A-Z’ characters.

Time Limit: 1 sec

Approaches

01 Approach

To encode an element, we need to encode its 'TAG' and ā€˜attributes’. If it doesn’t store a ā€˜VALUE’, we need to encode its children in the given order. For encoding the children, we first encode their 'TAG' and ā€˜attributes’, then encode their children, and so on. We stop this process when we reach an element that stores a ā€˜VALUE’. So, we need to encode the list of child elements recursively. 

 

Create a helper function ā€˜encodeHelper’ that takes parameters as an ā€˜element’ object, 'TAG' to integer mapping, and references to a string. The helper function encodes the passed element and appends it to the ā€˜RESULT’. After that, it traverses through the list of child elements and makes recursive calls to itself with the child element as a parameter. In the recursive call, it appends the encoded child element to ā€˜RESULT’. The recursion ends when an element that stores a ā€˜VALUE’ is reached.

 

The helper function, ā€˜encodeHelper(Object ā€˜ELEMENT’, Map 'TAG_TO_INT', String& ā€˜RESULT’)’:

 

  • Append ā€˜RESULT’ with the integer mapped to the 'TAG' of ā€˜ELEMENT’.
  • Run a loop where ā€˜i’ iterates through the list of attributes in ā€˜ELEMENT’:
    • Append ā€˜RESULT’ with the integer mapped to the 'TAG' of attribute ā€˜i’.
    • Append ā€˜RESULT’ with the ā€˜VALUE’ stored in the attribute ā€˜i’.
  • If the ā€˜VALUE’ in the ā€˜ELEMENT’ is not ā€˜NULL’, then append ā€˜RESULT’ with ā€˜VALUE’.
  • Else, run a loop where ā€˜i’ iterates through the list of children in ā€˜ELEMENT’:
    • Call the function ā€˜encodeHelper’ with parameters (ā€˜i’, 'TAG_TO_INT', ā€˜RESULT’).

 

In the ā€˜encodeXML’ function, we call ā€˜encodeHelper’ with parameters: (object of input ā€˜ELEMENT’, given 'TAG' to integer mapping, an empty string ā€˜RESULT’). The string ā€˜RESULT’ stores the converted output string.

 

  • Initialize ā€˜RESULT’ as an empty string.
  • Call function ā€˜encodeHelper’ with parameters (object of input ā€˜ELEMENT’, given 'TAG' to integer mapping, ā€˜RESULT’).
  • Return ā€˜RESULT’ as the answer.