@nodecfdi/cfdi-cleaner
Version:
Librería para limpiar comprobantes fiscales digitales v3.3 y v4.0
52 lines (51 loc) • 2.11 kB
JavaScript
import { Mixin } from 'ts-mixer';
import CfdiXPath from '#src/internal/cfdi_x_path';
import SchemaLocation from '#src/internal/schema_location';
import XmlAttributeMethods from '#src/mixins/xml_attribute_methods';
export default class RemoveIncompleteSchemaLocations extends Mixin(XmlAttributeMethods) {
clean(document) {
const xpath = CfdiXPath.createFromDocument(document);
const schemaLocations = xpath.querySchemaLocations();
for (const schemaLocation of schemaLocations) {
const value = this.cleanSchemaLocationValue(schemaLocation.value);
this.attributeSetValueOrRemoveIfEmpty(schemaLocation, value);
}
}
/**
* @param schemaLocationValue - SchemaLocation
*/
cleanSchemaLocationValue(schemaLocationValue) {
const pairs = this.schemaLocationValueNamespaceXsdPairToArray(schemaLocationValue);
const schemaLocation = new SchemaLocation(pairs);
return schemaLocation.asValue();
}
/**
* Parses schema location value skipping namespaces without xsd locations (identified by .xsd extension)
*
* @param schemaLocationValue - SchemaLocation
*/
schemaLocationValueNamespaceXsdPairToArray(schemaLocationValue) {
const components = SchemaLocation.valueToComponents(schemaLocationValue);
const pairs = {};
for (let c = 0; c < components.length; c += 1) {
const namespace = components[c];
if (this.uriEndsWithXsd(namespace)) {
// Namespace is a location
continue;
}
const location = components[c + 1] ?? '';
if (!this.uriEndsWithXsd(location)) {
// Location is a namespace
continue;
}
// Namespace match with location that ends with xsd
pairs[namespace] = location;
// eslint-disable-next-line sonarjs/updated-loop-counter
c += 1; // Skip ns declaration
}
return pairs;
}
uriEndsWithXsd(uri) {
return uri.toLowerCase().endsWith('.xsd');
}
}