An XML file includes tags
- Tags must have an opening and closing tag
- Tags can have additional attributes or outerText (text will not contain line breaks or blank spaces at the beginning and at the end)
- Ignore comments and xml version at the beginning of the file
Attention: For simplicity, we assume that the end of the xml file will end with the character ^, and in the file content there will be no ^ character in any other position.
SAMPLE TESTCASE:
INPUT
<code> Introduction to Algorithms
Thomas
Cormen
MIT Press
2009
89.99
</code>
<code> Introduction to Algorithms
Thomas
Cormen
MIT Press
2009
89.99
</code>
Introduction to Algorithms
Thomas
Cormen
MIT Press
2009
89.99
^
And here is my code, please help me to fill code on remove_newlines() and parse_xml(). I have fixed this for 2 days but it couldn’t run 🙁
<code> #define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <Stdbool.h>
// Define a structure to store tag attributes
typedef struct Attribute {
char* name;
char* value;
struct Attribute* next;
} Attribute;
// Defines a general tree node structure for XML tags
typedef struct TreeNode {
char* tag_name;
Attribute* attributes;
char* text;
struct TreeNode* first_child;
struct TreeNode* next_sibling;
struct TreeNode* parent;
} TreeNode;
// Function to create a new attribute
Attribute* create_attribute(char* name, char* value) {
Attribute* attr = (Attribute*)malloc(sizeof(Attribute));
attr->name = strdup(name);
attr->value = strdup(value);
attr->next = NULL;
return attr;
}
// Function to create a new tree node
TreeNode* create_tree_node(char* tag_name, char* text, TreeNode* parent) {
TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
node->tag_name = strdup(tag_name);
node->attributes = NULL;
node->text = text ? strdup(text) : NULL;
node->first_child = NULL;
node->next_sibling = NULL;
node->parent = parent;
return node;
}
// Function adds an attribute to the button
void add_attribute(TreeNode* node, char* name, char* value) {
Attribute* attr = create_attribute(name, value);
attr->next = node->attributes;
node->attributes = attr;
}
// Function adds a child node to the parent node
void add_child(TreeNode* parent, TreeNode* child) {
if (parent->first_child == NULL) {
parent->first_child = child;
}
else {
TreeNode* sibling = parent->first_child;
while (sibling->next_sibling != NULL) {
sibling = sibling->next_sibling;
}
sibling->next_sibling = child;
}
}
// Function to release the tree's memory
void free_tree(TreeNode* node) {
if (node == NULL) return;
free_tree(node->first_child);
free_tree(node->next_sibling);
free(node->tag_name);
if (node->text) free(node->text);
Attribute* attr = node->attributes;
while (attr != NULL) {
Attribute* next = attr->next;
free(attr->name);
free(attr->value);
free(attr);
attr = next;
}
free(node);
}
// Function reads until the delimiter character and returns the result string
char* read_until(const char** str, char delimiter) {
int capacity = 10;
char* buffer = (char*)malloc(capacity);
int length = 0;
char ch;
while ((ch = **str) != '' && ch != delimiter) {
if (length + 1 >= capacity) {
capacity *= 2;
buffer = (char*)realloc(buffer, capacity);
}
buffer[length++] = ch;
(*str)++;
}
if (ch == delimiter) {
(*str)++;
}
buffer[length] = '';
return buffer;
}
// Function to remove newline characters and leading and trailing blank characters in the string
void remove_newlines(char* str) {
// CODE HERE
}
// Function to check for self-closing tags
int is_self_closing_tag(const char* tag_name) {
// for futher implementation
return 0;
}
// Function to print tree according to general tree structure
void print_tree(TreeNode* node, int depth) {
if (node == NULL) return;
for (int i = 0; i < depth; i++) printf(" ");
printf("<%s", node->tag_name);
Attribute* attr = node->attributes;
while (attr != NULL) {
printf(" %s="%s"", attr->name, attr->value);
attr = attr->next;
}
printf(">");
bool isContainText = false;
if (node->text)
{
printf("%s", node->text);
isContainText = true;
}
else
printf("n");
print_tree(node->first_child, depth + 1);
if (!is_self_closing_tag(node->tag_name)) {
if(!isContainText) for (int i = 0; i < depth; i++) printf(" ");
printf("</%s>n", node->tag_name);
}
print_tree(node->next_sibling, depth);
}
// Function to parse XML tags and create a tree
TreeNode* parse_xml(const char* str) {
TreeNode* root = NULL;
// CODE HERE
return root;
}
// Function reads all input from keyboard up to ^
char* read_all_input() {
size_t capacity = 1024;
char* buffer = (char*)malloc(capacity);
size_t length = 0;
int ch;
while ((ch = getchar()) != '^') {
if (length + 1 >= capacity) {
capacity *= 2;
buffer = (char*)realloc(buffer, capacity);
}
buffer[length++] = ch;
}
buffer[length] = '';
return buffer;
}
int main() {
char* xml_content = read_all_input();
TreeNode* root = parse_xml(xml_content);
if (root) {
print_tree(root, 0);
free_tree(root);
}
else {
printf("Failed to parse XML.n");
}
return EXIT_SUCCESS;
}
</code>
<code> #define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <Stdbool.h>
// Define a structure to store tag attributes
typedef struct Attribute {
char* name;
char* value;
struct Attribute* next;
} Attribute;
// Defines a general tree node structure for XML tags
typedef struct TreeNode {
char* tag_name;
Attribute* attributes;
char* text;
struct TreeNode* first_child;
struct TreeNode* next_sibling;
struct TreeNode* parent;
} TreeNode;
// Function to create a new attribute
Attribute* create_attribute(char* name, char* value) {
Attribute* attr = (Attribute*)malloc(sizeof(Attribute));
attr->name = strdup(name);
attr->value = strdup(value);
attr->next = NULL;
return attr;
}
// Function to create a new tree node
TreeNode* create_tree_node(char* tag_name, char* text, TreeNode* parent) {
TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
node->tag_name = strdup(tag_name);
node->attributes = NULL;
node->text = text ? strdup(text) : NULL;
node->first_child = NULL;
node->next_sibling = NULL;
node->parent = parent;
return node;
}
// Function adds an attribute to the button
void add_attribute(TreeNode* node, char* name, char* value) {
Attribute* attr = create_attribute(name, value);
attr->next = node->attributes;
node->attributes = attr;
}
// Function adds a child node to the parent node
void add_child(TreeNode* parent, TreeNode* child) {
if (parent->first_child == NULL) {
parent->first_child = child;
}
else {
TreeNode* sibling = parent->first_child;
while (sibling->next_sibling != NULL) {
sibling = sibling->next_sibling;
}
sibling->next_sibling = child;
}
}
// Function to release the tree's memory
void free_tree(TreeNode* node) {
if (node == NULL) return;
free_tree(node->first_child);
free_tree(node->next_sibling);
free(node->tag_name);
if (node->text) free(node->text);
Attribute* attr = node->attributes;
while (attr != NULL) {
Attribute* next = attr->next;
free(attr->name);
free(attr->value);
free(attr);
attr = next;
}
free(node);
}
// Function reads until the delimiter character and returns the result string
char* read_until(const char** str, char delimiter) {
int capacity = 10;
char* buffer = (char*)malloc(capacity);
int length = 0;
char ch;
while ((ch = **str) != '' && ch != delimiter) {
if (length + 1 >= capacity) {
capacity *= 2;
buffer = (char*)realloc(buffer, capacity);
}
buffer[length++] = ch;
(*str)++;
}
if (ch == delimiter) {
(*str)++;
}
buffer[length] = '';
return buffer;
}
// Function to remove newline characters and leading and trailing blank characters in the string
void remove_newlines(char* str) {
// CODE HERE
}
// Function to check for self-closing tags
int is_self_closing_tag(const char* tag_name) {
// for futher implementation
return 0;
}
// Function to print tree according to general tree structure
void print_tree(TreeNode* node, int depth) {
if (node == NULL) return;
for (int i = 0; i < depth; i++) printf(" ");
printf("<%s", node->tag_name);
Attribute* attr = node->attributes;
while (attr != NULL) {
printf(" %s="%s"", attr->name, attr->value);
attr = attr->next;
}
printf(">");
bool isContainText = false;
if (node->text)
{
printf("%s", node->text);
isContainText = true;
}
else
printf("n");
print_tree(node->first_child, depth + 1);
if (!is_self_closing_tag(node->tag_name)) {
if(!isContainText) for (int i = 0; i < depth; i++) printf(" ");
printf("</%s>n", node->tag_name);
}
print_tree(node->next_sibling, depth);
}
// Function to parse XML tags and create a tree
TreeNode* parse_xml(const char* str) {
TreeNode* root = NULL;
// CODE HERE
return root;
}
// Function reads all input from keyboard up to ^
char* read_all_input() {
size_t capacity = 1024;
char* buffer = (char*)malloc(capacity);
size_t length = 0;
int ch;
while ((ch = getchar()) != '^') {
if (length + 1 >= capacity) {
capacity *= 2;
buffer = (char*)realloc(buffer, capacity);
}
buffer[length++] = ch;
}
buffer[length] = '';
return buffer;
}
int main() {
char* xml_content = read_all_input();
TreeNode* root = parse_xml(xml_content);
if (root) {
print_tree(root, 0);
free_tree(root);
}
else {
printf("Failed to parse XML.n");
}
return EXIT_SUCCESS;
}
</code>
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <Stdbool.h>
// Define a structure to store tag attributes
typedef struct Attribute {
char* name;
char* value;
struct Attribute* next;
} Attribute;
// Defines a general tree node structure for XML tags
typedef struct TreeNode {
char* tag_name;
Attribute* attributes;
char* text;
struct TreeNode* first_child;
struct TreeNode* next_sibling;
struct TreeNode* parent;
} TreeNode;
// Function to create a new attribute
Attribute* create_attribute(char* name, char* value) {
Attribute* attr = (Attribute*)malloc(sizeof(Attribute));
attr->name = strdup(name);
attr->value = strdup(value);
attr->next = NULL;
return attr;
}
// Function to create a new tree node
TreeNode* create_tree_node(char* tag_name, char* text, TreeNode* parent) {
TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
node->tag_name = strdup(tag_name);
node->attributes = NULL;
node->text = text ? strdup(text) : NULL;
node->first_child = NULL;
node->next_sibling = NULL;
node->parent = parent;
return node;
}
// Function adds an attribute to the button
void add_attribute(TreeNode* node, char* name, char* value) {
Attribute* attr = create_attribute(name, value);
attr->next = node->attributes;
node->attributes = attr;
}
// Function adds a child node to the parent node
void add_child(TreeNode* parent, TreeNode* child) {
if (parent->first_child == NULL) {
parent->first_child = child;
}
else {
TreeNode* sibling = parent->first_child;
while (sibling->next_sibling != NULL) {
sibling = sibling->next_sibling;
}
sibling->next_sibling = child;
}
}
// Function to release the tree's memory
void free_tree(TreeNode* node) {
if (node == NULL) return;
free_tree(node->first_child);
free_tree(node->next_sibling);
free(node->tag_name);
if (node->text) free(node->text);
Attribute* attr = node->attributes;
while (attr != NULL) {
Attribute* next = attr->next;
free(attr->name);
free(attr->value);
free(attr);
attr = next;
}
free(node);
}
// Function reads until the delimiter character and returns the result string
char* read_until(const char** str, char delimiter) {
int capacity = 10;
char* buffer = (char*)malloc(capacity);
int length = 0;
char ch;
while ((ch = **str) != '' && ch != delimiter) {
if (length + 1 >= capacity) {
capacity *= 2;
buffer = (char*)realloc(buffer, capacity);
}
buffer[length++] = ch;
(*str)++;
}
if (ch == delimiter) {
(*str)++;
}
buffer[length] = '';
return buffer;
}
// Function to remove newline characters and leading and trailing blank characters in the string
void remove_newlines(char* str) {
// CODE HERE
}
// Function to check for self-closing tags
int is_self_closing_tag(const char* tag_name) {
// for futher implementation
return 0;
}
// Function to print tree according to general tree structure
void print_tree(TreeNode* node, int depth) {
if (node == NULL) return;
for (int i = 0; i < depth; i++) printf(" ");
printf("<%s", node->tag_name);
Attribute* attr = node->attributes;
while (attr != NULL) {
printf(" %s="%s"", attr->name, attr->value);
attr = attr->next;
}
printf(">");
bool isContainText = false;
if (node->text)
{
printf("%s", node->text);
isContainText = true;
}
else
printf("n");
print_tree(node->first_child, depth + 1);
if (!is_self_closing_tag(node->tag_name)) {
if(!isContainText) for (int i = 0; i < depth; i++) printf(" ");
printf("</%s>n", node->tag_name);
}
print_tree(node->next_sibling, depth);
}
// Function to parse XML tags and create a tree
TreeNode* parse_xml(const char* str) {
TreeNode* root = NULL;
// CODE HERE
return root;
}
// Function reads all input from keyboard up to ^
char* read_all_input() {
size_t capacity = 1024;
char* buffer = (char*)malloc(capacity);
size_t length = 0;
int ch;
while ((ch = getchar()) != '^') {
if (length + 1 >= capacity) {
capacity *= 2;
buffer = (char*)realloc(buffer, capacity);
}
buffer[length++] = ch;
}
buffer[length] = '';
return buffer;
}
int main() {
char* xml_content = read_all_input();
TreeNode* root = parse_xml(xml_content);
if (root) {
print_tree(root, 0);
free_tree(root);
}
else {
printf("Failed to parse XML.n");
}
return EXIT_SUCCESS;
}
New contributor
Văn Hưởng Nguyễn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.