xpathGenerate method

String xpathGenerate({
  1. String? byId,
})

Returns an XPath string that can be used to query for this XmlNode.

If byId is giving a fully qualified attribute name, the presence of the attribute causes the generation of a shorter lookup expression.

Implementation

String xpathGenerate({String? byId}) {
  final result = <String>[];
  for (XmlNode? current = this; current != null; current = current.parent) {
    switch (current) {
      case XmlAttribute(qualifiedName: final name):
        result.add(_createSegment(current,
            where: (each) =>
                each is XmlAttribute && each.qualifiedName == name,
            filter: '@$name'));
      case XmlElement(qualifiedName: final name):
        if (byId != null) {
          final attribute = current.getAttributeNode(byId);
          if (attribute != null) {
            result.add('//*[@${attribute.toXmlString()}]');
            return result.reversed.join('/');
          }
        }
        result.add(_createSegment(current,
            where: (each) => each is XmlElement && each.qualifiedName == name,
            filter: name));
      case XmlText():
      case XmlCDATA():
        result.add(_createSegment(current,
            where: (each) => each is XmlText || each is XmlCDATA,
            filter: 'text()'));
      case XmlComment():
        result.add(_createSegment(current,
            where: (each) => each is XmlComment, filter: 'comment()'));
      case XmlProcessing():
        result.add(_createSegment(current,
            where: (each) => each is XmlProcessing,
            filter: 'processing-instruction()'));
      case XmlDocument():
        result.add(this == current ? '/' : '');
      default:
        result.add(
            _createSegment(current, where: (each) => true, filter: 'node()'));
    }
  }
  return result.reversed.join('/');
}