📄 element.c
字号:
node = ( IXML_Node * ) newAttr;
attrNode = element->n.firstAttr;
while( attrNode != NULL ) {
if( strcmp( attrNode->nodeName, node->nodeName ) == 0 ) {
break; //found it
} else {
attrNode = attrNode->nextSibling;
}
}
if( attrNode != NULL ) // already present, will replace by newAttr
{
preSib = attrNode->prevSibling;
nextSib = attrNode->nextSibling;
if( preSib != NULL ) {
preSib->nextSibling = node;
}
if( nextSib != NULL ) {
nextSib->prevSibling = node;
}
if( element->n.firstAttr == attrNode ) {
element->n.firstAttr = node;
}
if( rtAttr != NULL ) {
*rtAttr = ( IXML_Attr * ) attrNode;
}
} else // add this attribute
{
if( element->n.firstAttr != NULL ) {
prevAttr = element->n.firstAttr;
nextAttr = prevAttr->nextSibling;
while( nextAttr != NULL ) {
prevAttr = nextAttr;
nextAttr = prevAttr->nextSibling;
}
prevAttr->nextSibling = node;
node->prevSibling = prevAttr;
} else // this is the first attribute node
{
element->n.firstAttr = node;
node->prevSibling = NULL;
node->nextSibling = NULL;
}
if( rtAttr != NULL ) {
*rtAttr = NULL;
}
}
return IXML_SUCCESS;
}
/*================================================================
* ixmlElement_findAttributeNode
* Find a attribute node whose contents are the same as the oldAttr.
* Internal only to parser.
* Parameter:
* oldAttr: the attribute node to match
* Return:
* if found it, the attribute node is returned,
* otherwise, return NULL.
*
*=================================================================*/
IXML_Node *
ixmlElement_findAttributeNode( IN IXML_Element * element,
IN IXML_Attr * oldAttr )
{
IXML_Node *attrNode;
IXML_Node *oldAttrNode = ( IXML_Node * ) oldAttr;
assert( ( element != NULL ) && ( oldAttr != NULL ) );
attrNode = element->n.firstAttr;
while( attrNode != NULL ) { // parentNode, prevSib, nextSib and ownerDocument doesn't matter
if( ixmlNode_compare( attrNode, oldAttrNode ) == TRUE ) {
break; //found it
} else {
attrNode = attrNode->nextSibling;
}
}
return attrNode;
}
/*================================================================
* ixmlElement_removeAttributeNode
* Removes the specified attribute node.
* External function.
*
* Parameters:
* oldAttr: the attr node to remove from the attribute list.
*
* Return Value:
* IXML_SUCCESS or failure
*
*=================================================================*/
int
ixmlElement_removeAttributeNode( IN IXML_Element * element,
IN IXML_Attr * oldAttr,
OUT IXML_Attr ** rtAttr )
{
IXML_Node *attrNode;
IXML_Node *preSib,
*nextSib;
if( ( element == NULL ) || ( oldAttr == NULL ) ) {
return IXML_INVALID_PARAMETER;
}
attrNode = ixmlElement_findAttributeNode( element, oldAttr );
if( attrNode != NULL ) { // has the attribute
preSib = attrNode->prevSibling;
nextSib = attrNode->nextSibling;
if( preSib != NULL ) {
preSib->nextSibling = nextSib;
}
if( nextSib != NULL ) {
nextSib->prevSibling = preSib;
}
if( element->n.firstAttr == attrNode ) {
element->n.firstAttr = nextSib;
}
( IXML_Attr * ) attrNode->parentNode = NULL;
( IXML_Attr * ) attrNode->prevSibling = NULL;
( IXML_Attr * ) attrNode->nextSibling = NULL;
*rtAttr = ( IXML_Attr * ) attrNode;
return IXML_SUCCESS;
} else {
return IXML_NOT_FOUND_ERR;
}
}
/*================================================================
* ixmlElement_getElementsByTagName
* Returns a nodeList of all descendant Elements with a given
* tag name, in the order in which they are encountered in a preorder
* traversal of this element tree.
* External function.
*
* Parameters:
* tagName: the name of the tag to match on. The special value "*"
* matches all tags.
*
* Return Value:
* a nodeList of matching element nodes.
*
*=================================================================*/
IXML_NodeList *
ixmlElement_getElementsByTagName( IN IXML_Element * element,
IN char *tagName )
{
IXML_NodeList *returnNodeList = NULL;
if( ( element != NULL ) && ( tagName != NULL ) ) {
ixmlNode_getElementsByTagName( ( IXML_Node * ) element, tagName,
&returnNodeList );
}
return returnNodeList;
}
/*================================================================
* ixmlElement_getAttributeNS
* Retrieves an attribute value by local name and namespace URI.
* External function.
*
* Parameters:
* namespaceURI: the namespace URI of the attribute to retrieve.
* localName: the local name of the attribute to retrieve.
*
* Return Value:
* the attr value as a string, or NULL if that attribute does
* not have the specified value.
*
*=================================================================*/
DOMString
ixmlElement_getAttributeNS( IN IXML_Element * element,
IN DOMString namespaceURI,
IN DOMString localName )
{
IXML_Node *attrNode;
if( ( element == NULL ) || ( namespaceURI == NULL )
|| ( localName == NULL ) ) {
return NULL;
}
attrNode = element->n.firstAttr;
while( attrNode != NULL ) {
if( strcmp( attrNode->localName, localName ) == 0 && strcmp( attrNode->namespaceURI, namespaceURI ) == 0 ) { // found it
return attrNode->nodeValue;
} else {
attrNode = attrNode->nextSibling;
}
}
return NULL;
}
/*================================================================
* ixmlElement_setAttributeNS
* Adds a new attribute. If an attribute with the same local name
* and namespace URI is already present on the element, its prefix
* is changed to be the prefix part of the qualifiedName, and its
* value is changed to be the value parameter. This value is a
* simple string.
* External function.
*
* Parameter:
* namespaceURI: the namespace of the attribute to create or alter.
* qualifiedName: the qualified name of the attribute to create or alter.
* value: the value to set in string form.
*
* Return Value:
* IXML_SUCCESS or failure
*
*=================================================================*/
int
ixmlElement_setAttributeNS( IN IXML_Element * element,
IN DOMString namespaceURI,
IN DOMString qualifiedName,
IN DOMString value )
{
IXML_Node *attrNode = NULL;
IXML_Node newAttrNode;
IXML_Attr *newAttr;
int rc;
if( ( element == NULL ) || ( namespaceURI == NULL ) ||
( qualifiedName == NULL ) || ( value == NULL ) ) {
return IXML_INVALID_PARAMETER;
}
if( Parser_isValidXmlName( qualifiedName ) == FALSE ) {
return IXML_INVALID_CHARACTER_ERR;
}
ixmlNode_init( &newAttrNode );
newAttrNode.nodeName = strdup( qualifiedName );
if( newAttrNode.nodeName == NULL ) {
return IXML_INSUFFICIENT_MEMORY;
}
rc = Parser_setNodePrefixAndLocalName( &newAttrNode );
if( rc != IXML_SUCCESS ) {
Parser_freeNodeContent( &newAttrNode );
return rc;
}
// see DOM 2 spec page 59
if( ( newAttrNode.prefix != NULL && namespaceURI == NULL ) ||
( strcmp( newAttrNode.prefix, "xml" ) == 0 &&
strcmp( namespaceURI,
"http://www.w3.org/XML/1998/namespace" ) != 0 )
|| ( strcmp( qualifiedName, "xmlns" ) == 0
&& strcmp( namespaceURI,
"http://www.w3.org/2000/xmlns/" ) != 0 ) ) {
Parser_freeNodeContent( &newAttrNode );
return IXML_NAMESPACE_ERR;
}
attrNode = element->n.firstAttr;
while( attrNode != NULL ) {
if( strcmp( attrNode->localName, newAttrNode.localName ) == 0 &&
strcmp( attrNode->namespaceURI, namespaceURI ) == 0 ) {
break; //found it
} else {
attrNode = attrNode->nextSibling;
}
}
if( attrNode != NULL ) {
if( attrNode->prefix != NULL ) {
free( attrNode->prefix ); // remove the old prefix
}
// replace it with the new prefix
attrNode->prefix = strdup( newAttrNode.prefix );
if( attrNode->prefix == NULL ) {
Parser_freeNodeContent( &newAttrNode );
return IXML_INSUFFICIENT_MEMORY;
}
if( attrNode->nodeValue != NULL ) {
free( attrNode->nodeValue );
}
attrNode->nodeValue = strdup( value );
if( attrNode->nodeValue == NULL ) {
free( attrNode->prefix );
Parser_freeNodeContent( &newAttrNode );
return IXML_INSUFFICIENT_MEMORY;
}
} else {
// add a new attribute
rc = ixmlDocument_createAttributeNSEx( ( IXML_Document * )
element->n.ownerDocument,
namespaceURI, qualifiedName,
&newAttr );
if( rc != IXML_SUCCESS ) {
return rc;
}
newAttr->n.nodeValue = strdup( value );
if( newAttr->n.nodeValue == NULL ) {
ixmlAttr_free( newAttr );
return IXML_INSUFFICIENT_MEMORY;
}
if( ixmlElement_setAttributeNodeNS( element, newAttr, NULL ) !=
IXML_SUCCESS ) {
ixmlAttr_free( newAttr );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -