如何用换行中的特定元素替换多个<br/>标签?

时间:2019-04-18 08:16:32

标签: c# .net xml linq

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

它有效,但是如果<p>包含<b><i>之类的标签,则<>变成&lt;和{{1} } 分别。这就是为什么我想要一种&gt;方法或一种linq方法,以便能够在XML格式下进行更改。

请帮助。

foreach

我想要什么:

<?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>

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

我得到的是

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()})));
}

2 个答案:

答案 0 :(得分:2)

这可能不是最佳答案,但是它将满足您的大部分要求:

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();
}

答案 1 :(得分:0)

我想尝试一种不同的方法来查看它是否有效……通过利用正则表达式。它不像使用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>");
}