You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何仅替换XML文档里最后一处指定字符串值?

解决XML文档中仅替换最后一处指定字符串的问题

问题场景

有固定结构的XML文档(示例如下),需要仅将最后一处值为3023的字符串替换为2020,当前用Regex替换会修改所有匹配项,需要精准替换目标位置的内容。

XML示例文档

<cac:Party>
  <cbc:EndpointID schemeID="Country">3023</cbc:EndpointID>
  <cac:PartyIdentification>
    <cbc:ID schemeID="Country">3023</cbc:ID>
  </cac:PartyIdentification>
  <cac:PartyName>
    <cbc:Name>Test</cbc:Name>
  </cac:PartyName>
  <cac:PostalAddress>
    <cbc:AddressFormatCode listAgencyID="###" listID="urn:oioubl:codelist:addressformatcode-1.1">StructuredLax</cbc:AddressFormatCode>
    <cbc:StreetName>Test</cbc:StreetName>
    <cbc:CityName>Test</cbc:CityName>
    <cbc:PostalZone>Test</cbc:PostalZone>
    <cac:Country>
      <cbc:IdentificationCode>DK</cbc:IdentificationCode>
    </cac:Country>
  </cac:PostalAddress>
  <cac:PartyTaxScheme>
    <cbc:CompanyID schemeID="Country">3023</cbc:CompanyID>
    <cac:TaxScheme>
      <cbc:ID schemeID="urn:oioubl:id:taxschemeid-1.1" schemeAgencyID="320">63</cbc:ID>
      <cbc:Name>Moms</cbc:Name>
    </cac:TaxScheme>
  </cac:PartyTaxScheme>
  <cac:PartyLegalEntity>
    <cbc:RegistrationName>Test</cbc:RegistrationName>
    <cbc:CompanyID schemeID="Country">3023</cbc:CompanyID>

现有问题代码

当前使用StreamReader+StreamWriter+Regex的方式会替换所有3023:

string docText = null;
using (StreamReader sr = new StreamReader(filename))
{
    docText = sr.ReadToEnd();
}

Regex oldValue = new Regex("3023");
docText = oldValue.Replace(docText, "2020");

using (StreamWriter sw = new StreamWriter(filename))
{
    sw.Write(docText);
}

可行实现方案

方案1:利用LastIndexOf精准定位最后一处匹配

直接找到最后一个3023的起始索引,通过字符串拼接完成替换:

string docText = null;
using (StreamReader sr = new StreamReader(filename))
{
    docText = sr.ReadToEnd();
}

string target = "3023";
string replacement = "2020";
int lastIndex = docText.LastIndexOf(target);

if (lastIndex != -1)
{
    docText = docText.Substring(0, lastIndex) + replacement + docText.Substring(lastIndex + target.Length);
}

using (StreamWriter sw = new StreamWriter(filename))
{
    sw.Write(docText);
}

方案2:使用Regex替换最后一次匹配

通过MatchEvaluator结合计数器,仅替换最后一次匹配项:

string docText = null;
using (StreamReader sr = new StreamReader(filename))
{
    docText = sr.ReadToEnd();
}

string target = "3023";
string replacement = "2020";
int matchCount = Regex.Matches(docText, target).Count;
int currentCount = 0;

docText = Regex.Replace(docText, target, m => 
{
    currentCount++;
    return currentCount == matchCount ? replacement : m.Value;
});

using (StreamWriter sw = new StreamWriter(filename))
{
    sw.Write(docText);
}

方案3:解析XML节点精准修改(推荐)

因为处理的是XML文档,直接解析节点定位目标元素修改,避免字符串操作可能带来的格式问题:

using System.Xml.Linq;

// 加载XML文档
XDocument doc = XDocument.Load(filename);
// 定义XML命名空间(需与实际文档一致)
XNamespace cac = "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2";
XNamespace cbc = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2";

// 定位到目标节点:cac:PartyLegalEntity下的cbc:CompanyID
var targetNode = doc.Descendants(cac + "PartyLegalEntity")
                    .Elements(cbc + "CompanyID")
                    .LastOrDefault();

if (targetNode != null && targetNode.Value == "3023")
{
    targetNode.Value = "2020";
}

// 保存修改后的文档
doc.Save(filename);

注意:需根据实际XML文档的命名空间调整代码中的URI,确保节点定位准确。

内容的提问来源于stack exchange,提问作者user1845777

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 05:20:27