【问题标题】:How do I replace multiple <br/> tags with a specific element in a new line?如何用新行中的特定元素替换多个 <br/> 标签?
【发布时间】:2019-09-08 13:01:45
【问题描述】:

我有一个 XML 文件,其中包含多个 &lt;p&gt; 标记。一些&lt;p&gt; 标签中包含&lt;br/&gt;。所以,我应该为标签中的每个&lt;br/&gt; 创建一个新的XElement。我试图通过使用foreach 读取每一行并将每个&lt;br/&gt; 替换为&lt;/p&gt; + Environment.NewLine + &lt;p&gt; 来实现。

它可以工作,但如果&lt;p&gt; 包含&lt;b&gt;&lt;i&gt; 之类的标签,则&amp;lt;&amp;gt; 分别变为&amp;lt;&amp;gt;。这就是为什么,我想要一个 linq 方法或 foreach 方法,以便我能够在 XML 格式中进行更改。

请帮忙。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE repub SYSTEM "C:\repub\Repub_V1.dtd">
<?xml-stylesheet href="C:\repub\repub.xsl" type="text/xsl"?>
<repub>
<head>
<title>xxx</title>
</head>
<body>
<sec>
<title>First Title</title>
<break name="1-1"/>
<pps>This is Sparta</pps>
<h1><page num="1"/>First Heading</h1>
<bl>This is another text</bl>
<fig><img src="images/img_1-1.jpg" alt=""/><fc>This is a caption</fc></fig>
<p>This is a sentence<br/> that will be broken down <br/>into separate paragraph tags.</p>
</break>
</sec>
</body>
</repub>

我想要什么:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE repub SYSTEM "C:\repub\Repub_V1.dtd">
<?xml-stylesheet href="C:\repub\repub.xsl" type="text/xsl"?>
<repub>
<head>
<title>xxx</title>
</head>
<body>
<sec>
<title>First Title</title>
<break name="1-1"/>
<pps>This is Sparta</pps>
<h1><page num="1"/>First Heading</h1>
<bl>This is another text</bl>
<fig><img src="images/img_1-1.jpg" alt=""/><fc>This is a caption</fc></fig>
<p>This is a sentence</p>
<p>that will be broken down</p>
<p>into separate paragraph tags.</p>
</break>
</sec>
</body>
</repub>

我尝试了什么:

List<XElement> brs = xdoc.Descendants("br").ToList();
for (int i = brs.Count - 1; i >= 0; i--)
{
    brs[i].ReplaceWith(new XElement("br", new XElement("p", new object[] {brs[i].Attributes(), brs[i].Nodes()})));
}

在我的一个较早的问题中,我从 StackOverflow itslef 获得了这段代码。

我得到了什么:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE repub SYSTEM "C:\repub\Repub_V1.dtd">
<?xml-stylesheet href="C:\repub\repub.xsl" type="text/xsl"?>
<repub>
<head>
<title>xxx</title>
</head>
<body>
<sec>
<title>First Title</title>
<break name="1-1"/>
<pps>This is Sparta</pps>
<h1><page num="1"/>First Heading</h1>
<bl>This is another text</bl>
<fig><img src="images/img_1-1.jpg" alt=""/><fc>This is a caption</fc></fig>
<p>This is a sentence<br><p/></br> that will be broken down <br><p/></br>into separate paragraph tags.</p>
</break>
</sec>
</body>
</repub>

【问题讨论】:

  • 您是否考虑过使用正则表达式将换行符替换为段落标签?
  • 对这类事情使用正则表达式通常是一个非常糟糕的主意,因为 XML 不是常规语言。
  • 有什么建议吗?我现在被困在这一步了几天。
  • 我刚刚回答了。
  • 我原来的解决方案有效:for (int i = brs.Count - 1; i >= 0; i--) { brs[i].ReplaceWith(new XElement("p", new object [] { brs[i].Attributes(), brs[i].Nodes() })); }

标签: c# .net xml linq


【解决方案1】:

这可能不是最好的答案,但它可以满足您的大部分需求:

List<XElement> p = xdoc.Descendants("p").ToList();
for (int i = p.Count - 1; i >= 0; i--)
{
    var newP = new XElement("p");
    newP.ReplaceAttributes(p[i].Attributes());

    foreach (var node in p.Nodes())
    {
        if (node.NodeType == System.Xml.XmlNodeType.Element && ((XElement)node).Name == "br")
        {
            p[i].AddBeforeSelf(newP);
            newP = new XElement("p");
            newP.ReplaceAttributes(p[i].Attributes());
        }
        else
        {
            newP.Add(node);
        }
    }
    p[i].AddBeforeSelf(newP);
    p[i].Remove();
}

【讨论】:

    【解决方案2】:

    我想尝试一种不同的方法,看看它是否可行……通过利用正则表达式。它不像使用 XML 文档那样优雅,但尝试起来很有趣。

    void Main()
    {
        string info = @"<?xml version=""1.0"" encoding=""UTF-8""?>
        <!DOCTYPE repub SYSTEM ""C:\repub\Repub_V1.dtd"">
        <?xml-stylesheet href=""C:\repub\repub.xsl"" type=""text/xsl""?>
        <repub>
        <head>
        <title>xxx</title>
        </head>
        <body>
        <sec>
        <title>First Title</title>
        <break name=""1-1""/>
        <pps>This is Sparta</pps>
        <h1><page num=""1""/>First Heading</h1>
        <bl>This is another text</bl>
        <fig><img src=""images/img_1-1.jpg"" alt=""""/><fc>This is a caption</fc></fig>
        <p>This is a sentence<br/> that will be broken down <br/>into separate paragraph tags.</p>
        </break>
        </sec>
        </body>
        </repub>";
    
        string result = null;
        try
        {
            Regex regexObj = new Regex("<p>(.*?)</p>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            result = regexObj.Replace(info, new MatchEvaluator(ConvertBR));
            result.Dump();
        }
        catch (ArgumentException ex)
        {
            // Syntax error in the regular expression
        }
    }
    
    public String ConvertBR(Match m)
    {
        return m.Value.Replace("<br/>","</p><p>");
    }
    

    【讨论】:

      猜你喜欢
      • 2015-08-15
      • 1970-01-01
      • 2015-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-13
      相关资源
      最近更新 更多