parseString static method
List<XmlDoctype> ?
parseString(
- String string, {
- bool parseCharacterEntities = true,
- bool parseComments = false,
- bool trimWhitespace = true,
- bool parseCdataAsText = true,
- int start = 0,
- int? stop,
override
Returns a list of every XML DocType declaration 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
.
Returns null
if no Doctype Declarations are found.
Implementation
static List<XmlDoctype>? parseString(
String string, {
bool parseCharacterEntities = true,
bool parseComments = false,
bool trimWhitespace = true,
bool parseCdataAsText = true,
int start = 0,
int? stop,
}) {
if (!parseComments) string = string.removeComments();
if (trimWhitespace) string = string.trimWhitespace();
final doctypes = <XmlDoctype>[];
final tags = _delimiter.allMatches(string);
if (tags.isEmpty || start >= tags.length) return null;
for (var tag in tags) {
if (tag.namedGroup('isMarkup') != '!') continue;
if (tag.namedGroup('doctype') != 'DOCTYPE') continue;
final doctype =
Delimiters.doctype.firstMatch(string.substring(tag.start, tag.end))!;
final element = doctype.namedGroup('name');
if (element == null) continue;
// Capture and parse the external DTD values, if thye exist.
final identifier = doctype.namedGroup('identifier');
String? externalDtdName;
var externalDtd = doctype.namedGroup('externalDtd');
if (externalDtd != null) {
final externalDtdParts =
RegExp('".*?"|\'.?\'').allMatches(externalDtd).toList();
if (externalDtdParts.length > 1) {
final name = externalDtdParts.first;
externalDtdName = externalDtd.substring(name.start + 1, name.end - 1);
final path = externalDtdParts[1];
externalDtd = externalDtd.substring(path.start + 1, path.start - 1);
} else {
externalDtd = externalDtd.stripDelimiters();
}
}
// Caputre and parse the internal DTD value, if it exists.
final internalDtdValue = doctype.namedGroup('internalDtd');
List<XmlNode>? internalDtd;
if (internalDtdValue != null) {
internalDtd = XmlNode.parseString(
internalDtdValue,
parseCharacterEntities: parseCharacterEntities,
parseComments: true,
trimWhitespace: false,
parseCdataAsText: true,
);
}
doctypes.add(
XmlDoctype(
element: element,
isPublic: identifier == 'PUBLIC',
isSystem: identifier == 'SYSTEM',
externalDtdName: externalDtdName,
externalDtdUri: externalDtd,
internalDtd: internalDtd,
),
);
}
if (doctypes.isEmpty) return null;
return doctypes;
}