0

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));
2
  • Is there some reason you're doing this with a regex instead of an XML parser? Commented May 15, 2014 at 14:34
  • 2
    Besides the replacement you are using is wrong, you shoud replace with "$1" + repl + "$4" instead of "$1" + repl + "$3". The capture group $3 is getting the value inside the tags. See the example here Commented May 15, 2014 at 14:43

3 Answers 3

4

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(); 
Sign up to request clarification or add additional context in comments.

1 Comment

I have updated my question. Your first solution works but linq to XML would be much better, but I have no idea where to even start.
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...

1 Comment

Or the replacement is wrong... replacing with "$1" + repl + "$4" should work
1

Consider the following:

var result = Regex.Replace(s, string.Format(@"(?<={0}.*?\>).*(?=<)", key), repl);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.