Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Modifying namespace difinitions in schema file

Status
Not open for further replies.

RickBeddoe

Programmer
Nov 18, 2008
32
0
0
US
Hello folks.

Having a tough time trying to figure this one out.

I have a schema (xsd) file with namespaces declared in the root element as shown:


<xsd:schema xmlns:xsd=" xmlns:ci-com="
I would like to change the definition of this attribute from this:

xmlns:ci-com="
to this:

xmlns:ci-com="
I am doing this in VBA (with DOM interface) and everything I've tried kicks up an error that the attribute is read only. Here is the code:

newNode.nodeValue = newAttValue

where newNode is the root node (<xsd:schema...>) and newAttValue is a string representing the new vallue.


Any help would be appreciated.
 
tsuji

I know where the VBA forum is, but I thin this is more related to XML and DOM. Regardless of whether it's VBA, C# or Java, this would still be an issue.
 
That is vba specific (msxml2 object model). Besides, xml forum was not up to your need, according to my browsing your profile.
 
Fair enough.

However, take the programming language out of the Equation. How would you do something like this? XSLT?
 
In case anyone comes across this thread in the future, here's the solution:

Basically, use the 'setNamedItem' method of the Attributes property.


Function replaceAttributeValue(ByRef doc As DOMDocument60, xmlNode As IXMLDOMNode, oldAttValue As String, newAttValue As String) As IXMLDOMElement

Dim nodeLst As IXMLDOMNodeList
Dim nodeElem As IXMLDOMElement
Dim elmAttrs As IXMLDOMNamedNodeMap
Dim elmAttr As IXMLDOMAttribute
Dim newAttr As IXMLDOMAttribute
Dim replAttrValue As String
Dim ns As String, nsNodeName As String

' Get all the attributes in the node
Set elmAttrs = xmlNode.Attributes

'iterate through the attributes
For Each elmAttr In elmAttrs

If InStr(elmAttr.Value, oldAttValue) > 0 Then
'to use setNamedItem, you need a new node
'you need a namespace to make the new node
ns = elmAttr.namespaceURI

nsNodeName = elmAttr.nodeName
Set newNode = doc.createNode(NODE_ATTRIBUTE, nsNodeName, ns)
newNode.nodeValue = Replace(elmAttr.nodeValue, oldAttValue, newAttValue)
xmlNode.Attributes.setNamedItem newNode

End If
Next
Set replaceAttributeValue = xmlNode

'iterate through any childnodes
If xmlNode.hasChildNodes Then
Set nodeLst = xmlNode.selectNodes("*")
For Each nodeElem In nodeLst
Set nodeElem = replaceAttributeValue(doc, nodeElem, oldAttValue, newAttValue)
Next
End If


End Function
 
[0] I am not sure you've taken note that there might be cases which break the logic reflected in the function. Cases are:
[0.1] appearing ci-com:somename before or after namespace declaration of ci-com with nodeValue containing oldAttValue;
[0.2] default namespace declaration containing oldAttValue (which is basically the old namespace of ci-com).

[1] With all shortcomings aside, the central part of it should be written rather like this to make the logic robust.
[tt]
For Each elmAttr In elmAttrs

If InStr(elmAttr.Value, oldAttValue) > 0 Then
'to use setNamedItem, you need a new node
'you need a namespace to make the new node
ns = elmAttr.namespaceURI
nsNodeName = elmAttr.nodeName
[red]if nsNodeName="xmlns" or left(nsNodeName,6)="xmlns:" then[/red]
Set newNode = doc.createNode(NODE_ATTRIBUTE, nsNodeName, ns)
newNode.nodeValue = Replace(elmAttr.nodeValue, oldAttValue, newAttValue)
xmlNode.Attributes.setNamedItem newNode
[red]else
elmAttr.nodeValue=replace(elmAttr.nodeValue, oldAttValue, newAttValue)
end if[/red]
End If
Next
[/tt]
 
Good point tsuji

I do know for a fact that 0.1 will never happen in our case. But, 0.2 may happen in very few cases for our application.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top