XMLUtils.cpp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/NonnullOwnPtr.h>
  7. #include <LibXML/DOM/Node.h>
  8. #include "Parser/XMLUtils.h"
  9. namespace JSSpecCompiler {
  10. bool contains_empty_text(XML::Node const* node)
  11. {
  12. return node->as_text().builder.string_view().trim_whitespace().is_empty();
  13. }
  14. ParseErrorOr<StringView> deprecated_get_attribute_by_name(XML::Node const* node, StringView attribute_name)
  15. {
  16. auto const& attribute = node->as_element().attributes.get(attribute_name);
  17. if (!attribute.has_value())
  18. return ParseError::create(String::formatted("Attribute {} is not present", attribute_name), node);
  19. return attribute.value();
  20. }
  21. Optional<StringView> get_attribute_by_name(XML::Node const* node, StringView attribute_name)
  22. {
  23. auto const& attribute = node->as_element().attributes.get(attribute_name);
  24. if (!attribute.has_value())
  25. return {};
  26. return attribute.value();
  27. }
  28. ParseErrorOr<StringView> get_text_contents(XML::Node const* node)
  29. {
  30. auto const& children = node->as_element().children;
  31. if (children.size() != 1 || !children[0]->is_text())
  32. return ParseError::create("Expected single text node in a child list of the node"sv, node);
  33. return children[0]->as_text().builder.string_view();
  34. }
  35. ParseErrorOr<XML::Node const*> get_only_child(XML::Node const* element, StringView tag_name)
  36. {
  37. XML::Node const* result = nullptr;
  38. for (auto const& child : element->as_element().children) {
  39. TRY(child->content.visit(
  40. [&](XML::Node::Element const& element) -> ParseErrorOr<void> {
  41. if (element.name != tag_name)
  42. return ParseError::create(String::formatted("Expected child with the tag name {} but found {}", tag_name, element.name), child);
  43. if (result != nullptr)
  44. return ParseError::create("Element must have only one child"sv, child);
  45. result = child;
  46. return {};
  47. },
  48. [&](XML::Node::Text const&) -> ParseErrorOr<void> {
  49. if (!contains_empty_text(child))
  50. return ParseError::create("Element should not have non-empty child text nodes"sv, element);
  51. return {};
  52. },
  53. move(ignore_comments)));
  54. }
  55. if (result == nullptr)
  56. return ParseError::create(String::formatted("Element must have only one child"), element);
  57. return result;
  58. }
  59. }