Question

I need to replace the value of an element. The element and the namespace will be dynamic.

I think there is something wrong with my regex.

string key = "BusinessID";
Regex x = new Regex("(<" + key  + "(.*)" + "'>)(.*)(</" + key + ">)");
string s = @"<BusinessID xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</BusinessID>";
string repl = "the replacement text";
string Result = x.Replace(s, "$1" + repl + "$3");

Current Result:

<BusinessID xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>the replacement textstring

Desired Result:

<BusinessID xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>the replacement text</BusinessID>

How can I achieve this?

Extended for more complex scenario:

I have a List<KeyValuePair<string, object>> that I need to update the XML with the value from the object. The Key will align with the XML element.

The complete XML:

<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
<soap:Body>
    <CreateQueuedMsg xmlns='http://tempuri.org/'>
        <Token xmlns='http://tempuri.org/'>string</Token>
        <BGSMSMessage>
            <BusinessID xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</BusinessID>
            <CommsGUID xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</CommsGUID>
            <DestinationAddress xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</DestinationAddress>
            <Msg xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</Msg>
            <MsgEncodingType xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</MsgEncodingType>
            <SendDT xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>dateTime</SendDT>
            <SystemID xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</SystemID>
            <ValidityDT xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>dateTime</ValidityDT>
        </BGSMSMessage>
        <smsRoute>
            <SMSRoute xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</SMSRoute>
            <SMSRoute xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</SMSRoute>
        </smsRoute>
    </CreateQueuedMsg>
</soap:Body>
</soap:Envelope>

The object:

List<KeyValuePair<string, object>> lKVP = new List<KeyValuePair<string, object>>();

List<SMSRoute> smsRoute = new List<SMSRoute> { SMSRoute.BGWASP, SMSRoute.GrapeVine };
lKVP.Add(new KeyValuePair<string, object>("Token", "AD1518D9-4110-411E-11A5-762B14919797"));
lKVP.Add(new KeyValuePair<string, object>("BusinessID", BusinessID.Test));
lKVP.Add(new KeyValuePair<string, object>("CommsGUID", Guid.NewGuid().ToString()));
lKVP.Add(new KeyValuePair<string, object>("DestinationAddress", "0722222222"));
lKVP.Add(new KeyValuePair<string, object>("Msg", "Testers" + DateTime.Now.ToString()));
lKVP.Add(new KeyValuePair<string, object>("MsgEncodingType", BGSMSDataCodings.Default));
lKVP.Add(new KeyValuePair<string, object>("SendDT", DateTime.Now));
lKVP.Add(new KeyValuePair<string, object>("SystemID", SystemID.Test));
lKVP.Add(new KeyValuePair<string, object>("ValidityDT", DateTime.Now.AddDays(3)));
lKVP.Add(new KeyValuePair<string, object>("smsRoute", smsRoute));
Was it helpful?

Solution 2

You have some extra parentheses there, this works:

string key = "BusinessID";
Regex x = new Regex("(<" + key + ".*" + "'>)(.*)(</" + key + ">)");
string s = @"<BusinessID xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</BusinessID>";
string repl = "the replacement text";
string Result = x.Replace(s, "$1" + repl + "$3");

And James is right, you should use LINQ to XML for this...

OTHER TIPS

You appear to be using the wrong tool for the job, use LINQ to XML instead e.g.

var element = XElement.Parse("<BusinessID xmlns='http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes'>string</BusinessID>");
element.Value = "New value";
var xml = element.ToString();

Assuming the code in your question is in fact simplified, here's a more complete example which queries an actual XML document

var xdoc = XDocument.Parse("...");
var xname = XName.Get("BusinessID", "http://schemas.datacontract.org/2004/07/BG.Bus.Mobile.Classes");
var businessId = xdoc.Descendants(xname).FirstOrDefault();
businessId.Value = "New value";
string result = xdoc.ToString(); 

Consider the following:

var result = Regex.Replace(s, string.Format(@"(?<={0}.*?\>).*(?=<)", key), repl);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top