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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.