首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将XElement内容替换为XElement

将XElement内容替换为XElement
EN

Stack Overflow用户
提问于 2016-01-06 20:18:51
回答 5查看 1.7K关注 0票数 2

是否有一种方法可以选择性地将XElement内容替换为其他XElements?

我有一个XML:

代码语言:javascript
复制
<prompt>
   There is something I want to tell you.[pause=3]
   You are my favorite caller today.[pause=1]
   Have a great day!
</prompt>

我想把它渲染成这样:

代码语言:javascript
复制
<prompt>
   There is something I want to tell you.<break time="3s"/>
   You are my favorite caller today.<break time="1s"/>
   Have a great day!
</prompt>

我需要用实际的XElements替换占位符,但是当我试图更改XElement的内容时,.NET当然会转义所有尖括号。我理解为什么通常需要正确转义内容,但我需要绕过这种行为,直接将XML注入内容。

这是我的代码,否则会起作用。

代码语言:javascript
复制
MatchCollection matches = Regex.Matches(content, @"\[(\w+)=(\d+)]");
foreach (XElement element in voiceXmlDocument.Descendants("prompt"))
{
    if (matches[0] == null)
        continue;
    element.Value = element.Value.Replace(matches[0].Value, @"<break time=""5s""/>");
}

这是一项正在进行的工作,所以不要太担心RegEx模式的有效性,因为我稍后会解决这个问题,以匹配几个条件。这是概念代码的证明,重点是替换所描述的占位符。我在这里只包含了迭代和RegEx代码,以说明我需要能够对已经填充了内容的整个文档这样做。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-01-06 20:53:29

您可以使用XElement.Parse()方法:

首先,获取XElement的外部xml,例如,

代码语言:javascript
复制
string outerXml = element.ToString();

您完全可以使用此字符串:

代码语言:javascript
复制
<prompt>
  There is something I want to tell you.[pause=3]
  You are my favorite caller today.[pause=1]
  Have a great day!
</prompt>

然后你可以做你的替代品

代码语言:javascript
复制
outerXml = outerXml.Replace(matches[0].Value, @"<break time=""5s""/>");

然后,您可以将其解析回:

代码语言:javascript
复制
XElement repElement = XElement.Parse(outerXml);

最后,替换原始的XElement:

代码语言:javascript
复制
element.ReplaceWith(repElement);
票数 2
EN

Stack Overflow用户

发布于 2016-01-06 20:46:41

所有这些的关键是XText,它允许您将文本作为元素处理。

这是循环:

代码语言:javascript
复制
foreach (XElement prompt in voiceXmlDocument.Descendants("prompt"))
{
    string text = prompt.Value;  
    prompt.RemoveAll();
    foreach (string phrase in text.Split('['))
    {
        string[] parts = phrase.Split(']');
        if (parts.Length > 1)
        {
            string[] pause = parts[0].Split('=');
            prompt.Add(new XElement("break", new XAttribute("time", pause[1])));
            // add a + "s" if you REALLY want it, but then you have to get rid
            // of it later in some other code.
        }
        prompt.Add(new XText(parts[parts.Length - 1]));
    }
}

这是最终的结果

代码语言:javascript
复制
<prompt>
      There is something I want to tell you.<break time="3" />
      You are my favorite caller today.<break time="1" />
      Have a great day!
</prompt>
票数 0
EN

Stack Overflow用户

发布于 2016-01-06 21:13:19

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        var xml = 
            @"<prompt>There is something I want to tell you.[pause=3] You are my favorite caller today.[pause=1] Have a great day!</prompt>";

        var voiceXmlDocument = XElement.Parse(xml);

        var pattern = new Regex(@"\[(\w+)=(\d+)]");

        foreach (var element in voiceXmlDocument.DescendantsAndSelf("prompt"))
        {
            var matches = pattern.Matches(element.Value);

            foreach (var match in matches)
            {
                var matchValue = match.ToString();

                var number = Regex.Match(matchValue, @"\d+").Value;

                var newValue = string.Format(@"<break time=""{0}""/>", number);

                element.Value = element.Value.Replace(matchValue, newValue); 
            }

        }

        Console.WriteLine(voiceXmlDocument.ToString());
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34641988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档