private static validateName()

in src/language/semantics/xsltTokenDiagnostics.ts [157:276]


  private static validateName(
    name: string,
    type: ValidationType,
    xmlnsPrefixes: string[],
    elementStack?: ElementData[],
    expectedAttributes?: string[]
  ): NameValidationError {
    let valid = NameValidationError.None
    if (name.trim().length === 0) {
      return NameValidationError.NameError
    }
    if (
      type === ValidationType.XMLAttribute ||
      type === ValidationType.XSLTAttribute
    ) {
      if (
        name === 'xml:space' ||
        name === 'xml:lang' ||
        name === 'xml:base' ||
        name === 'xml:id'
      ) {
        return NameValidationError.None
      }
    }
    let nameParts = name.split(':')
    if (nameParts.length > 2) {
      return NameValidationError.NameError
    } else {
      if (nameParts.length === 2) {
        let prefix = nameParts[0]
        if (type === ValidationType.XMLElement) {
          // TODO: when within literal result element, iterate up stack until we get to an XSLT instruction:
          const expectedNames: string[] =
            elementStack && elementStack.length > 0
              ? elementStack[elementStack.length - 1].expectedChildElements
              : ['xsl:transform', 'xsl:stylesheet', 'xsl:package']
          if (prefix === 'xsl' || prefix === 'ixsl') {
            if (expectedNames.length === 0 && elementStack) {
              const withinNextIteration =
                elementStack[elementStack.length - 1].symbolName ===
                'xsl:next-iteration'
              valid =
                name === 'xsl:with-param' && withinNextIteration
                  ? NameValidationError.None
                  : NameValidationError.XSLTElementNameError
            } else {
              valid =
                expectedNames.indexOf(name) > -1
                  ? NameValidationError.None
                  : NameValidationError.XSLTElementNameError
              if (
                valid !== NameValidationError.None &&
                (name === 'xsl:next-iteration' || name === 'xsl:break')
              ) {
                const withinIterarator = elementStack?.find(
                  (item) => item.symbolName === 'xsl:iterate'
                )
                if (withinIterarator) {
                  valid = NameValidationError.None
                }
              }
            }
            return valid
          } else {
            valid =
              xmlnsPrefixes.indexOf(prefix) > -1
                ? NameValidationError.None
                : NameValidationError.NamespaceError
          }
        } else if (prefix === 'xsl' && type === ValidationType.XSLTAttribute) {
          // TODO: for attributes on non-xsl instructions, check that name is in the attributeGroup: xsl:literal-result-element-attributes (e.g. xsl:expand-text)
          //valid = xmlnsPrefixes.indexOf(prefix) > -1? NameValidationError.None: NameValidationError.NamespaceError;
        } else {
          valid =
            xmlnsPrefixes.indexOf(prefix) > -1
              ? NameValidationError.None
              : NameValidationError.NamespaceError
        }
      } else if (
        (type === ValidationType.XSLTAttribute ||
          type === ValidationType.XMLAttribute) &&
        expectedAttributes
      ) {
        valid =
          expectedAttributes.indexOf(name) > -1
            ? NameValidationError.None
            : NameValidationError.XSLTAttributeNameError
        return valid
      }
      if (valid === NameValidationError.None) {
        nameParts.forEach((namePart) => {
          if (valid === NameValidationError.None) {
            let charsOK = true
            let firstChar = true
            let charExists = false
            for (let s of namePart) {
              if (firstChar) {
                firstChar = false
                charExists = true
                charsOK = XsltTokenDiagnostics.nameStartCharRgx.test(s)
                if (!charsOK) {
                  break
                }
              } else {
                charsOK = XsltTokenDiagnostics.nameCharRgx.test(s)
                if (!charsOK) {
                  break
                }
              }
            }
            valid =
              charExists && charsOK
                ? NameValidationError.None
                : NameValidationError.NameError
          }
        })
      }
    }
    return valid
  }