📄 xmldtdvalidator.java
字号:
"MSG_FIXED_ATTVALUE_INVALID", args, XMLErrorReporter.SEVERITY_ERROR); } } if (fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_ENTITY || fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_ENUMERATION || fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_ID || fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_IDREF || fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_NMTOKEN || fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_NOTATION ) { validateDTDattribute(elementName, attrValue, fTempAttDecl); } } // for all attributes } // addDTDDefaultAttrsAndValidate(int,XMLAttrList) /** Checks entities in attribute values for standalone VC. */ protected String getExternalEntityRefInAttrValue(String nonNormalizedValue) { int valLength = nonNormalizedValue.length(); int ampIndex = nonNormalizedValue.indexOf('&'); while (ampIndex != -1) { if (ampIndex + 1 < valLength && nonNormalizedValue.charAt(ampIndex+1) != '#') { int semicolonIndex = nonNormalizedValue.indexOf(';', ampIndex+1); String entityName = nonNormalizedValue.substring(ampIndex+1, semicolonIndex); entityName = fSymbolTable.addSymbol(entityName); int entIndex = fDTDGrammar.getEntityDeclIndex(entityName); if (entIndex > -1) { fDTDGrammar.getEntityDecl(entIndex, fEntityDecl); if (fEntityDecl.inExternal || (entityName = getExternalEntityRefInAttrValue(fEntityDecl.value)) != null) { return entityName; } } } ampIndex = nonNormalizedValue.indexOf('&', ampIndex+1); } return null; } // isExternalEntityRefInAttrValue(String):String /** * Validate attributes in DTD fashion. */ protected void validateDTDattribute(QName element, String attValue, XMLAttributeDecl attributeDecl) throws XNIException { switch (attributeDecl.simpleType.type) { case XMLSimpleType.TYPE_ENTITY: { // NOTE: Save this information because invalidStandaloneAttDef boolean isAlistAttribute = attributeDecl.simpleType.list; try { if (isAlistAttribute) { fValENTITIES.validate(attValue, fValidationState); } else { fValENTITY.validate(attValue, fValidationState); } } catch (InvalidDatatypeValueException ex) { fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, ex.getKey(), ex.getArgs(), XMLErrorReporter.SEVERITY_ERROR ); } break; } case XMLSimpleType.TYPE_NOTATION: case XMLSimpleType.TYPE_ENUMERATION: { boolean found = false; String [] enumVals = attributeDecl.simpleType.enumeration; if (enumVals == null) { found = false; } else for (int i = 0; i < enumVals.length; i++) { if (attValue == enumVals[i] || attValue.equals(enumVals[i])) { found = true; break; } } if (!found) { StringBuffer enumValueString = new StringBuffer(); if (enumVals != null) for (int i = 0; i < enumVals.length; i++) { enumValueString.append(enumVals[i]+" "); } fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "MSG_ATTRIBUTE_VALUE_NOT_IN_LIST", new Object[]{attributeDecl.name.rawname, attValue, enumValueString}, XMLErrorReporter.SEVERITY_ERROR); } break; } case XMLSimpleType.TYPE_ID: { try { fValID.validate(attValue, fValidationState); } catch (InvalidDatatypeValueException ex) { fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, ex.getKey(), ex.getArgs(), XMLErrorReporter.SEVERITY_ERROR ); } break; } case XMLSimpleType.TYPE_IDREF: { boolean isAlistAttribute = attributeDecl.simpleType.list;//Caveat - Save this information because invalidStandaloneAttDef try { if (isAlistAttribute) { fValIDRefs.validate(attValue, fValidationState); } else { fValIDRef.validate(attValue, fValidationState); } } catch (InvalidDatatypeValueException ex) { if (isAlistAttribute) { fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "IDREFSInvalid", new Object[]{attValue}, XMLErrorReporter.SEVERITY_ERROR ); } else { fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, ex.getKey(), ex.getArgs(), XMLErrorReporter.SEVERITY_ERROR ); } } break; } case XMLSimpleType.TYPE_NMTOKEN: { boolean isAlistAttribute = attributeDecl.simpleType.list;//Caveat - Save this information because invalidStandaloneAttDef //changes fTempAttDef try { if (isAlistAttribute) { fValNMTOKENS.validate(attValue, fValidationState); } else { fValNMTOKEN.validate(attValue, fValidationState); } } catch (InvalidDatatypeValueException ex) { if (isAlistAttribute) { fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "NMTOKENSInvalid", new Object[] { attValue}, XMLErrorReporter.SEVERITY_ERROR); } else { fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "NMTOKENInvalid", new Object[] { attValue}, XMLErrorReporter.SEVERITY_ERROR); } } break; } } // switch } // validateDTDattribute(QName,String,XMLAttributeDecl) /** Returns true if invalid standalone attribute definition. */ protected boolean invalidStandaloneAttDef(QName element, QName attribute) { // REVISIT: This obviously needs to be fixed! -Ac boolean state = true; /* if (fStandaloneReader == -1) { return false; } // we are normalizing a default att value... this ok? if (element.rawname == -1) { return false; } return getAttDefIsExternal(element, attribute); */ return state; } // // Private methods // /** * Normalize the attribute value of a non CDATA attributes collapsing * sequences of space characters (x20) * * @param attributes The list of attributes * @param index The index of the attribute to normalize */ private boolean normalizeAttrValue(XMLAttributes attributes, int index) { // vars boolean leadingSpace = true; boolean spaceStart = false; boolean readingNonSpace = false; int count = 0; int eaten = 0; String attrValue = attributes.getValue(index); char[] attValue = new char[attrValue.length()]; fBuffer.setLength(0); attrValue.getChars(0, attrValue.length(), attValue, 0); for (int i = 0; i < attValue.length; i++) { if (attValue[i] == ' ') { // now the tricky part if (readingNonSpace) { spaceStart = true; readingNonSpace = false; } if (spaceStart && !leadingSpace) { spaceStart = false; fBuffer.append(attValue[i]); count++; } else { if (leadingSpace || !spaceStart) { eaten ++; /*** BUG #3512 *** int entityCount = attributes.getEntityCount(index); for (int j = 0; j < entityCount; j++) { int offset = attributes.getEntityOffset(index, j); int length = attributes.getEntityLength(index, j); if (offset <= i-eaten+1) { if (offset+length >= i-eaten+1) { if (length > 0) length--; } } else { if (offset > 0) offset--; } attributes.setEntityOffset(index, j, offset); attributes.setEntityLength(index, j, length); } /***/ } } } else { readingNonSpace = true; spaceStart = false; leadingSpace = false; fBuffer.append(attValue[i]); count++; } } // check if the last appended character is a space. if (count > 0 && fBuffer.charAt(count-1) == ' ') { fBuffer.setLength(count-1); /*** BUG #3512 *** int entityCount = attributes.getEntityCount(index); for (int j=0; j < entityCount; j++) { int offset = attributes.getEntityOffset(index, j); int length = attributes.getEntityLength(index, j); if (offset < count-1) { if (offset+length == count) { length--; } } else { offset--; } attributes.setEntityOffset(index, j, offset); attributes.setEntityLength(index, j, length); } /***/ } String newValue = fBuffer.toString(); attributes.setValue(index, newValue); return ! attrValue.equals(newValue); } /** Root element specified. */ private final void rootElementSpecified(QName rootElement) throws XNIException { if (fPerformValidation) { String root1 = fRootElement.rawname; String root2 = rootElement.rawname; if (root1 == null || !root1.equals(root2)) { fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN, "RootElementTypeMustMatchDoctypedecl", new Object[]{root1, root2}, XMLErrorReporter.SEVERITY_ERROR); } } } // rootElementSpecified(QName) /** * Check that the content of an element is valid. * <p> * This is the method of primary concern to the validator. This method is called * upon the scanner reaching the end tag of an element. At that time, the * element's children must be structurally validated, so it calls this method. * The index of the element being checked (in the decl pool), is provided as * well as an array of element name indexes of the children. The validator must * confirm that this element can have these children in this order. * <p> * This can also be called to do 'what if' testing of content models just to see * if they would be valid. * <p> * Note that the element index is an index into the element decl pool, whereas * the children indexes are name indexes, i.e. into the string pool. * <p> * A value of -1 in the children array indicates a PCDATA node. All other * indexes will be positive and represent child elements. The count can be * zero, since some elements have the EMPTY content model and that must be * confirmed. * * @param elementIndex The index within the <code>ElementDeclPool</code> of
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -