1

任何人都可以帮助我尝试组合嵌套的跨度标签吗?

我有一些生成的 HTML 试图整理,但我无法让这部分工作。示例 HTML:

<p>
  <strong>
    <span style="font-family:arial,sans-serif">
      <span style="color:black">
        <span style="font-size:medium">HELLO</span>
      </span>
    </span>
  </strong>
</p>

我想要做的是将跨度标签组合成一个具有组合样式的标签,所以输出是:

<p>
  <strong>
    <span style="font-family:arial,sans-serif;color:black;font-size:medium">HELLO</span>
  </strong>
</p>

我在 asp.net 4.0 中使用 C#

谢谢,迈克

4

5 回答 5

1

我想出了这个解决方案,它不是一种单行的解决方案,但它是这样的:假设你有一个名为 的变量中的 HTML 文本foo,那么你可以执行以下操作:

string replacement1 = "\"";
string replacement2 = "</span>";
string pattern = @"(?<=<span style=\")[^\"]+"; //Will match all the style strings
string pattern1 = @"(?<=<span style=)(.|\s)+\"(?=>[^<>].+</span>)"; //Will match from the first " to the last " before HELLO
string pattern2 = @"(</span>\s*)+"; //Will match any number of </span> tags
Regex rgx = new Regex(pattern);
MatchCollection matches = rgx.Matches(foo);
foreach (Match match in matches)
    replacement1 += match.Value + ";"; //Builds the new styles string
replacement1 += "\"";
Regex rgx = new Regex(pattern1);
string result = rgx.Replace(foo, replacement1); //Replace the multiple span style tags with a single one
Regex rgx = new Regex(pattern2); 
string result = rgx.Replace(foo, replacement2); //Replace the multiple closing span tags with a single one

第一次更换后,你应该得到

<p>
  <strong>
    <span style="font-family:arial,sans-serif;color:black;font-size:medium">HELLO</span>
      </span>
    </span>
  </strong>
</p>

在第二次替换之后:

<p>
  <strong>
    <span style="font-family:arial,sans-serif;color:black;font-size:medium">HELLO</span>
  </strong>
</p>

我无法测试它(它可能有一些拼写错误),但它应该可以工作!

于 2013-06-10T13:42:24.350 回答
0

您可以使用 jQuery 来获得预期的结果:

var css = "";
$("span").each(function (i) {
  css += $(this).attr('style')+';';
});
$("span").children().unwrap('<span>');
$("span").attr('style', css);
于 2013-06-11T08:03:10.773 回答
0

这是我使用名为 Html Agility Pack ( http://htmlagilitypack.codeplex.com/ ) 的 HTML Parser 的 1.4.6 版编写的解决方案。将此库添加到您的项目以使用以下代码。

var doc = new HtmlDocument();
doc.LoadHtml(INPUT);
foreach(var currentSpanNode in doc.DocumentNode.SelectNodes("//span")) {
    var parentNode = currentSpanNode.ParentNode;
    if (parentNode.Name != "span") continue;
    MergeStyleValuesLeft(parentNode.Attributes["style"], currentSpanNode.Attributes["style"]);
    parentNode.RemoveChild(currentSpanNode);
    parentNode.AppendChildren(currentSpanNode.ChildNodes);
}

var sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
doc.Save(sw);

此时,您的新 HTML 代码位于 StringBuilder 对象中。上面的代码使用了一个名为 MergeStyleValuesLeft() 的函数。我在这里有这个函数的简单版本。根据您的要求,您可以改进它以处理重复的样式。

private void MergeStyleValuesLeft(HtmlAttribute leftAttribute, HtmlAttribute rightAttribute) {
    if (leftAttribute == null || rightAttribute == null) return;
    char[] styleSeparators = "; ".ToCharArray();
    string leftValue = leftAttribute.Value.Trim(styleSeparators);
    string rightValue = rightAttribute.Value.Trim(styleSeparators);
    leftAttribute.Value = String.Format("{0};{1}", leftValue, rightValue);
}
于 2013-06-11T12:19:36.010 回答
0

对不起,自从我问了这个问题后就离开了,同时一位同事看了看,想出了一个解决方案。

正如我上面对 Brad 的评论,我发布的 HTML 是一个非常精简的示例,这里是我们使用的测试代码的链接http://paste2.org/48hX9tpF

我的同事是这样做的:首先找到嵌套打开

String outputHTML;
Regex re = new Regex("<span style=\"(.*?)\">(<span style=\"(.*?)\">)+", RegexOptions.IgnoreCase);
outputHTML = re.Replace(inputHTML, new MatchEvaluator(StyleMerger));

static string StyleMerger(Match regexMatch)
{
    String matchedText = regexMatch.ToString();
    return matchedText.Replace("\"><span style=\"", ";");
}

然后查找并替换嵌套的关闭标签

re = new Regex("</span>(</span>)+", RegexOptions.IgnoreCase);
outputHTML = re.Replace(outputHTML, "</span>");

这导致了这个 HTML http://paste2.org/xWFOKH3F

于 2013-06-21T13:20:39.217 回答
-2

<strong>应该放在<span>标签之后。还有一个名为 font-weight 的样式属性,您可以将其设置为粗体。

<p>
    <span style="font-family:arial,sans-serif;color:black;font-size:medium;font-weight:bold">HELLO</span>
</p>
于 2013-06-10T13:03:00.117 回答