parseString static method
- String string, {
- bool parseCharacterEntities = true,
- bool parseComments = false,
- bool trimWhitespace = true,
- bool parseCdataAsText = true,
- bool global = false,
- List<
String> ? returnElementsNamed, - List<
String> ? returnElementsWithId, - List<
String> ? returnElementsWithAttributesNamed, - List<
XmlAttribute> ? returnElementsWithAttributes, - bool matchAllAttributes = true,
- int start = 0,
- int? stop,
Returns a list of every element found in string
.
string
must not be null
.
If parseCharacterEntities
is true
, text values will be parsed
and replace all encoded character entities with their corresponding
character. parseCharacterEntities
must not be null
.
If parseComments
is true
, commments will be scrubbed
from string
before parsing.
If trimWhitespace
is true
, unnecessary whitespace between nodes
will be removed and all remaining whitespace will be replaced with
a single space. trimWhitespace
must not be null
.
If parseCdataAsText
is true
, all CDATA sections will be
returned as XmlText nodes. parseCdataAsText
must not be null
.
If global
is true
, all elements will be returned regardless
of whether they're nested within other elements. If false
, only
the root level elements will be returned.
If returnElementsNamed
is not null
, only elements with a name
contained in returnElementsNamed
will be returned.
If returnElementsWithId
is not null
, only elements with an ID
contained in returnElementsWithId
will be returned.
If returnElementsWithAttributesNamed
is not null
,
only elements posessing an attribute with a name contained in
returnElementsWithAttributesNamed
will be returned.
If matchAllAttributes
is true
, an element must possess
every attribute contained in returnElementsWithAttributesNamed
to be returned, if false
, the element only needs to posess a
single attribute contained in returnElementsWithAttributesNamed
.
If returnElementsWithAttributes
is not null
, only elements
possessing attributes with an identical name and value as those
contained in returnElemtnsWithAttribute
will be returned.
If matchAllAttributes
is true
, an element must possess every
attribute contained in returnElementsWithAttributes
, if false
,
the element only needs to possess a single attribute contained in
returnElementsWithAttributes
.
start
and stop
refer to the indexes of the identified elements.
Only matches found between start
and stop
will be returned.
start
must not be null
and must be >= 0
. stop
may be null
,
but must be >= start
if provided.
Returns null
if no elements were found.
Implementation
static List<XmlElement>? parseString(
String string, {
bool parseCharacterEntities = true,
bool parseComments = false,
bool trimWhitespace = true,
bool parseCdataAsText = true,
bool global = false,
List<String>? returnElementsNamed,
List<String>? returnElementsWithId,
List<String>? returnElementsWithAttributesNamed,
List<XmlAttribute>? returnElementsWithAttributes,
bool matchAllAttributes = true,
int start = 0,
int? stop,
}) {
assert(start >= 0);
assert(stop == null || stop >= start);
if (!parseComments) string = string.removeComments();
if (trimWhitespace) string = string.trimWhitespace();
final elements = <XmlElement>[];
var elementCount = 0;
while (string.contains(Delimiters.elementTag)) {
var tag = Delimiters.elementTag.firstMatch(string);
final name = tag!.namedGroup('tagName');
if (!name!.startsWith('/')) {
if (returnElementsNamed == null || returnElementsNamed.contains(name)) {
List<XmlNode>? children;
final attributeData = tag.namedGroup('attributes')!.trim();
if (tag.namedGroup('isEmpty') != '/') {
tag = Delimiters.element(name, global: global).firstMatch(string);
children = XmlNode.parseString(
tag!.namedGroup('children')!,
parseCharacterEntities: parseCharacterEntities,
parseComments: true,
trimWhitespace: false,
parseCdataAsText: parseCdataAsText,
);
}
List<XmlAttribute>? attributes;
var attriubtesAreValid = true;
if (attributeData.isNotEmpty) {
attributes = XmlAttribute.parseString(
attributeData,
parseCharacterEntities: parseCharacterEntities,
trimWhitespace: false,
)!;
if (returnElementsWithAttributesNamed != null ||
returnElementsWithAttributes != null) {
var attributeNamesToValidate =
(returnElementsWithAttributesNamed != null)
? (matchAllAttributes)
? returnElementsWithAttributesNamed.length
: 1
: 0;
var attributesToValidate = (returnElementsWithAttributes != null)
? (matchAllAttributes)
? returnElementsWithAttributes.length
: 1
: 0;
for (var attribute in attributes) {
if (attributeNamesToValidate > 0 &&
returnElementsWithAttributesNamed!
.contains(attribute.name)) {
attributeNamesToValidate--;
}
if (attributesToValidate > 0 &&
returnElementsWithAttributes!.contains(attribute)) {
attributesToValidate--;
}
if (attributeNamesToValidate <= 0 &&
attributesToValidate <= 0) {
break;
}
}
if (attributeNamesToValidate > 0 || attributesToValidate > 0) {
attriubtesAreValid = false;
}
}
} else if (returnElementsWithAttributes != null &&
returnElementsWithAttributes.isNotEmpty) {
attriubtesAreValid = false;
}
if (attriubtesAreValid) {
final id = attributes
?.cast<XmlAttribute?>()
.firstWhere((attribute) => attribute!.name == 'id',
orElse: () => null)
?.value;
if (elementCount >= start &&
(returnElementsWithId == null ||
returnElementsWithId.contains(id))) {
elements.add(
XmlElement(
name: name,
attributes: attributes,
children: children,
),
);
if (stop != null && elementCount > stop) break;
}
elementCount++;
}
}
}
string = string.substring(tag.end);
}
if (elements.isEmpty) return null;
return elements;
}