/** * Create an XML Indenter * * @param next the next receiver in the pipeline, always an XMLEmitter */ public XMLIndenter(XMLEmitter next) { super(next); emitter = next; bufferedAttributes = new AttributeCollectionImpl(getConfiguration()); }
/** * Notify an attribute. Attributes are notified after the startElement event, and before any * children. */ public void attribute(NodeName nameCode, SimpleType typeCode, CharSequence value, Location locationId, int properties) throws XPathException { int index = pendingAttributes.findByNodeName(nameCode); if (index < 0) { pendingAttributes.addAttribute(nameCode, typeCode, value.toString(), locationId, properties); } else { pendingAttributes.setAttribute(index, nameCode, typeCode, value.toString(), locationId, properties); } }
/** * Get the attribute value using its fingerprint */ /*@Nullable*/ public String getValueByFingerprint(int fingerprint) { int index = findByFingerprint(fingerprint); return (index < 0 ? null : getValue(index)); }
/** * Get the value of an attribute (by name). * * @param uri The namespace uri of the attribute. * @param localname The local name of the attribute. * @return The index position of the attribute */ /*@Nullable*/ public String getValue(String uri, String localname) { int index = findByName(uri, localname); return (index < 0 ? null : getValue(index)); }
/** * Get the type of an attribute (by name). * * @param uri The namespace uri of the attribute. * @param localname The local name of the attribute. * @return The index position of the attribute */ /*@Nullable*/ public String getType(String uri, String localname) { int index = findByName(uri, localname); return (index < 0 ? null : getType(index)); }
/** * startContent: Add any namespace undeclarations needed to stop * namespaces being inherited from parent elements */ public void startContent() throws XPathException { inStartTag = false; int props = elementProperties | ReceiverOptions.NAMESPACE_OK; if (hasChildren) { props |= ReceiverOptions.HAS_CHILDREN; } nextReceiver.startElement(elementNameCode, elementTypeCode, elementLocationId, props); declareNamespacesForStartElement(); final int length = bufferedAttributes.getLength(); for (int i = 0; i < length; i++) { nextReceiver.attribute(bufferedAttributes.getNodeName(i), bufferedAttributes.getTypeAnnotation(i), bufferedAttributes.getValue(i), bufferedAttributes.getLocation(i), bufferedAttributes.getProperties(i) | ReceiverOptions.NAMESPACE_OK); } acceptAttributes = false; nextReceiver.startContent(); }
/** * Index all the ID attributes. This is done the first time the id() function * is used on this document, or the first time that id() is called after a sequence of updates */ private void indexIDs() { if (idTable != null) { return; // ID's are already indexed } idTable = new HashMap<>(256); NodeImpl curr = this; NodeImpl root = curr; while (curr != null) { if (curr.getNodeKind() == Type.ELEMENT) { //noinspection ConstantConditions ElementImpl e = (ElementImpl) curr; if (e.isId()) { registerID(e, Whitespace.trim(e.getStringValueCS())); } AttributeCollectionImpl atts = (AttributeCollectionImpl) e.getAttributeList(); for (int i = 0; i < atts.getLength(); i++) { if (!atts.isDeleted(i) && atts.isId(i) && NameChecker.isValidNCName(Whitespace.trim(atts.getValue(i)))) { // don't index any invalid IDs - these can arise when using a non-validating parser registerID(e, Whitespace.trim(atts.getValue(i))); } } } curr = curr.getNextInDocument(root); } }
attributeList = new AttributeCollectionImpl(getConfiguration()); int index = atts.findByNodeName(nameCode); if (index == -1) { atts.addAttribute(nameCode, attType, value.toString(), ExplicitLocation.UNKNOWN_LOCATION, 0); } else { throw new IllegalStateException(
/** * Get the type of an attribute (by lexical QName). * * @param name The lexical QName of the attribute. * @return The attribute type as a string (e.g. "NMTOKEN", or * "CDATA" if no declaration was read). */ /*@NotNull*/ public String getType(/*@NotNull*/ String name) { int index = getIndex(name); return getType(index); }
/** * Get the value of an attribute (by lexnical QName). * * @param name The attribute name (a lexical QName). * The prefix must match the prefix originally used. This method is defined in SAX, but is * not recommended except where the prefix is null. */ /*@Nullable*/ public String getValue(/*@NotNull*/ String name) { int index = getIndex(name); return getValue(index); }
public void attribute(NodeName attName, SimpleType typeCode, /*@NotNull*/ CharSequence value, Location locationId, int properties) throws XPathException { properties &= ~ReceiverOptions.DISABLE_ESCAPING; if (contentStarted) { throw new IllegalStateException("attribute() called after startContent()"); } if (attributes == null) { attributes = new AttributeCollectionImpl(config); } if (attName.hasURI(NamespaceConstant.XML) && attName.getLocalPart().equals("id")) { value = Whitespace.trim(value); } attributes.addAttribute(attName, typeCode, value.toString(), locationId, properties); }
/** * Find an attribute by node name * * @param nodeName the name of the required attribute * @return the index of the attribute, or -1 if absent */ public int findByNodeName(/*@NotNull*/ NodeName nodeName) { if (props == null || config == null) { return -1; } if (nodeName.hasFingerprint()) { return findByFingerprint(nodeName.getFingerprint()); } else { return findByName(nodeName.getURI(), nodeName.getLocalPart()); } }
/** * Notify the start of the content, that is, the completion of all attributes and namespaces. * Note that the initial receiver of output from XSLT instructions will not receive this event, * it has to detect it itself. Note that this event is reported for every element even if it has * no attributes, no namespaces, and no content. */ public void startContent() throws XPathException { try { if (depth > 0 || !requireWellFormed) { String uri = pendingElement.getURI(); String localName = pendingElement.getLocalPart(); String qname = pendingElement.getDisplayName(); handler.startElement(uri, localName, qname, pendingAttributes); elementStack.push(uri); elementStack.push(localName); elementStack.push(qname); pendingAttributes.clear(); pendingElement = null; } } catch (SAXException err) { handleSAXException(err); } }
/** * Create an attribute list as a copy of an existing attribute list * * @param atts the existing attribute list to be copied * @return the copied attribute list. Note that if the original attribute list * is empty, the method returns the singleton object {@link #EMPTY_ATTRIBUTE_COLLECTION}; * this case must therefore be handled specially if the returned attribute list is to * be modified. */ /*@Nullable*/ public static AttributeCollectionImpl copy(/*@NotNull*/ AttributeCollectionImpl atts) { if (atts.getLength() == 0) { return EMPTY_ATTRIBUTE_COLLECTION; } AttributeCollectionImpl t = new AttributeCollectionImpl(atts.config); t.used = atts.used; t.names = new NodeName[atts.used]; t.values = new String[atts.used]; t.props = new int[atts.used]; t.locations = new Location[atts.used]; System.arraycopy(atts.names, 0, t.names, 0, atts.used); System.arraycopy(atts.values, 0, t.values, 0, atts.used); System.arraycopy(atts.props, 0, t.props, 0, atts.used); System.arraycopy(atts.locations, 0, t.locations, 0, atts.used); if (atts.types != null) { t.types = new SimpleType[atts.used]; System.arraycopy(atts.types, 0, t.types, 0, atts.used); } return t; }
/** * Notify an attribute. Attributes are notified after the startElement event, and before any * children. Namespaces and attributes may be intermingled. * * @param nameCode The name of the attribute * @param typeCode The type of the attribute * @param locationId the location of the node in the source, or of the instruction that created it * @param properties Bit significant value. The following bits are defined: * <dl> * <dd>DISABLE_ESCAPING</dd> <dt>Disable escaping for this attribute</dt> * <dd>NO_SPECIAL_CHARACTERS</dd> <dt>Attribute value contains no special characters</dt> * </dl> * @throws IllegalStateException: attempt to output an attribute when there is no open element * start tag */ public void attribute(NodeName nameCode, SimpleType typeCode, CharSequence value, Location locationId, int properties) throws XPathException { if (inMetaTag) { attributes.addAttribute(nameCode, typeCode, value.toString(), locationId, properties); } else { nextReceiver.attribute(nameCode, typeCode, value, locationId, properties); } }
/** * Get the index of an attribute (by name). * * @param uri The namespace uri of the attribute. * @param localname The local name of the attribute. * @return The index position of the attribute, or -1 if absent */ public int getIndex(String uri, String localname) { return findByName(uri, localname); }
/** * Get the index, given the fingerprint. * Return -1 if not found. */ public int getIndexByFingerprint(int fingerprint) { return findByFingerprint(fingerprint); }
/** * Determine if the current element has any attributes * * @return true if the element has one or more attributes */ public boolean hasAttributes() { return bufferedAttributes.getLength() > 0; }
attributes = AttributeCollectionImpl.EMPTY_ATTRIBUTE_COLLECTION; } else { attributes.compact();
/** * startContent: Add any namespace undeclarations needed to stop * namespaces being inherited from parent elements */ public void startContent() throws XPathException { inStartTag = false; int props = elementProperties | ReceiverOptions.NAMESPACE_OK; if (hasChildren) { props |= ReceiverOptions.HAS_CHILDREN; } nextReceiver.startElement(elementNameCode, elementTypeCode, elementLocationId, props); declareNamespacesForStartElement(); final int length = bufferedAttributes.getLength(); for (int i = 0; i < length; i++) { nextReceiver.attribute(bufferedAttributes.getNodeName(i), bufferedAttributes.getTypeAnnotation(i), bufferedAttributes.getValue(i), bufferedAttributes.getLocation(i), bufferedAttributes.getProperties(i) | ReceiverOptions.NAMESPACE_OK); } acceptAttributes = false; nextReceiver.startContent(); }