누구든지 html 문자열을 분할 (작은 mce 편집기에서 생성)하고 C #을 사용하여 N 부분으로 분할하는 예가 있습니까?
나는 쪼개지는 단어없이 끈을 균등하게 나눌 필요가있다.
html을 분할하고 HtmlAgilityPack을 사용하여 깨진 태그를 수정하려고했습니다. 이상적으로 그것은 html이 아닌 텍스트에 기반을 둔 purley가되어야하는 것처럼 분리 점을 찾는 방법을 모르겠지만.
아무도이 문제를 해결하는 방법에 대한 아이디어가 없습니까?
최신 정보
요청에 따라 다음은 입력 및 원하는 출력의 예입니다.
입력:
<p><strong>Lorem ipsum dolor sit amet, <em>consectetur adipiscing</em></strong> elit.</p>
출력 (3 열로 나눠 질 때) :
Part1: <p><strong>Lorem ipsum dolor</strong></p>
Part2: <p><strong>sit amet, <em>consectetur</em></strong></p>
Part3: <p><strong><em>adipiscing</em></strong> elit.</p>
업데이트 2 :
방금 방금 깔끔한 HTML과 연극을했고 그것은 깨진 태그를 고칠 때 잘 작동하는 것 같습니다. 그래서 이것이 분할 파인트를 찾을 수있는 방법을 찾을 수 있다면 좋을 것입니다.
업데이트 3
.NET C #의 전체 단어에 대해이 자르기 문자열 과 비슷한 방법을 사용하여 각 부분을 구성하는 일반 텍스트 단어의 목록을 가져 왔습니다. 그럼, 깔끔한 HTML을 사용하여 말 HTML에 대한 유효한 XML 구조를 가지고 있으며,이 단어 목록이 주어지면 이제는 누가 그것을 분할하는 가장 좋은 방법이 될지에 대한 아이디어를 얻었습니까?
업데이트 4
누구든지 HTML을 사용하여 색인을 찾기 위해 정규식을 사용하여 다음과 같은 문제를 볼 수 있습니까?
일반 텍스트 문자열 "sit amet, consectetur"이 주어지면 모든 공간을 정규식 "(\ s | <(. | \ n) +?>) *"으로 바꾸고, 이론적으로 공백 및 / 또는 태그들
그런 다음 깨진 HTML 태그를 수정하기 위해 단정 한 HTML을 사용할 수 있습니까?
많은 감사
매트
이봐, 이건 내 저주 다 ! 나는 명백하게 그것에 시간의 무리한 양을 포함하여 -에 - 및 - 지출없이 문제에서 떠날 수 없다.
나는 이것에 대해 생각했다. HTML Tidy에 대해 생각해 보았지만 작동 할 수는 있었지만 주위를 감싸는 데 어려움이있었습니다.
그래서, 나는 내 자신의 해결책을 썼다.
나는 당신의 의견과 내가 함께 던진 다른 의견에 대해 이것을 시험했다. 그것은 꽤 잘 작동하는 것 같습니다. 확실히 거기에 구멍이 있지만 출발점을 제공 할 수 있습니다.
어쨌든, 내 접근 방식은 이것이었다 :
HtmlWord
클래스에서 구현했습니다. HtmlLine
클래스에서 구현했습니다. HtmlAgilityPack.HtmlNode
객체에서 즉시 직관적으로 바로 액세스 할 수 있도록 몇 가지 확장 메소드를 작성하십시오. 아래의 HtmlHelper
클래스에서 구현했습니다. 이 모든 일에 미쳤나요? 아마도, 네. 그러나 다른 방법을 찾아 낼 수 없다면, 이것을 시도해 볼 수 있습니다.
샘플 입력과 함께 작동하는 방법은 다음과 같습니다.
var document = new HtmlDocument();
document.LoadHtml("<p><strong>Lorem ipsum dolor sit amet, <em>consectetur adipiscing</em></strong> elit.</p>");
var nodeToSplit = document.DocumentNode.SelectSingleNode("p");
var lines = nodeToSplit.SplitIntoLines(3);
foreach (var line in lines)
Console.WriteLine(line.ToString());
산출:
<p><strong>Lorem ipsum dolor </strong></p>
<p><strong>sit amet, <em>consectetur </em></strong></p>
<p><strong><em>adipiscing </em></strong>elit. </p>
이제 코드를 위해 :
using System;
using System.Collections.Generic;
using System.Linq;
using HtmlAgilityPack;
public class HtmlWord {
public string Text { get; private set; }
public HtmlNode[] NodeStack { get; private set; }
// convenience property to display list of ancestors cleanly
// (for ease of debugging)
public string NodeList {
get { return string.Join(", ", NodeStack.Select(n => n.Name).ToArray()); }
}
internal HtmlWord(string text, HtmlNode node, HtmlNode top) {
Text = text;
NodeStack = GetNodeStack(node, top);
}
private static HtmlNode[] GetNodeStack(HtmlNode node, HtmlNode top) {
var nodes = new Stack<HtmlNode>();
while (node != null && !node.Equals(top)) {
nodes.Push(node);
node = node.ParentNode;
};
return nodes.ToArray();
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using HtmlAgilityPack;
[Flags()]
public enum NodeChange {
None = 0,
Dropped = 1,
Added = 2
}
public class HtmlLine {
private List<HtmlWord> _words;
public IList<HtmlWord> Words {
get { return _words.AsReadOnly(); }
}
public int WordCount {
get { return _words.Count; }
}
public HtmlLine(IEnumerable<HtmlWord> words) {
_words = new List<HtmlWord>(words);
}
private static NodeChange CompareNodeStacks(HtmlWord x, HtmlWord y, out HtmlNode[] droppedNodes, out HtmlNode[] addedNodes) {
var droppedList = new List<HtmlNode>();
var addedList = new List<HtmlNode>();
// traverse x's NodeStack backwards to see which nodes
// do not include y (and are therefore "finished")
foreach (var node in x.NodeStack.Reverse()) {
if (!Array.Exists(y.NodeStack, n => n.Equals(node)))
droppedList.Add(node);
}
// traverse y's NodeStack forwards to see which nodes
// do not include x (and are therefore "new")
foreach (var node in y.NodeStack) {
if (!Array.Exists(x.NodeStack, n => n.Equals(node)))
addedList.Add(node);
}
droppedNodes = droppedList.ToArray();
addedNodes = addedList.ToArray();
NodeChange change = NodeChange.None;
if (droppedNodes.Length > 0)
change &= NodeChange.Dropped;
if (addedNodes.Length > 0)
change &= NodeChange.Added;
// could maybe use this in some later revision?
// not worth the effort right now...
return change;
}
public override string ToString() {
if (WordCount < 1)
return string.Empty;
var lineBuilder = new StringBuilder();
using (var lineWriter = new StringWriter(lineBuilder))
using (var xmlWriter = new XmlTextWriter(lineWriter)) {
var firstWord = _words[0];
foreach (var node in firstWord.NodeStack) {
xmlWriter.WriteStartElement(node.Name);
foreach (var attr in node.Attributes)
xmlWriter.WriteAttributeString(attr.Name, attr.Value);
}
xmlWriter.WriteString(firstWord.Text + " ");
for (int i = 1; i < WordCount; ++i) {
var previousWord = _words[i - 1];
var word = _words[i];
HtmlNode[] droppedNodes;
HtmlNode[] addedNodes;
CompareNodeStacks(
previousWord,
word,
out droppedNodes,
out addedNodes
);
foreach (var dropped in droppedNodes)
xmlWriter.WriteEndElement();
foreach (var added in addedNodes) {
xmlWriter.WriteStartElement(added.Name);
foreach (var attr in added.Attributes)
xmlWriter.WriteAttributeString(attr.Name, attr.Value);
}
xmlWriter.WriteString(word.Text + " ");
if (i == _words.Count - 1) {
foreach (var node in word.NodeStack)
xmlWriter.WriteEndElement();
}
}
}
return lineBuilder.ToString();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using HtmlAgilityPack;
public static class HtmlHelper {
public static IList<HtmlLine> SplitIntoLines(this HtmlNode node, int wordsPerLine) {
var lines = new List<HtmlLine>();
var words = node.GetWords(node.ParentNode);
for (int i = 0; i < words.Count; i += wordsPerLine) {
lines.Add(new HtmlLine(words.Skip(i).Take(wordsPerLine)));
}
return lines.AsReadOnly();
}
public static IList<HtmlWord> GetWords(this HtmlNode node, HtmlNode top) {
var words = new List<HtmlWord>();
if (node.HasChildNodes) {
foreach (var child in node.ChildNodes)
words.AddRange(child.GetWords(top));
} else {
var textNode = node as HtmlTextNode;
if (textNode != null && !string.IsNullOrEmpty(textNode.Text)) {
string[] singleWords = textNode.Text.Split(
new string[] {" "},
StringSplitOptions.RemoveEmptyEntries
);
words.AddRange(
singleWords
.Select(w => new HtmlWord(w, node.ParentNode, top)
)
);
}
}
return words.AsReadOnly();
}
}
되풀이해서 말하자면, 이것은 함께 던집니다. 나는 그것이 문제가 있다고 확신한다. 고려해야 할 출발점으로 만 제시합니다. 다른 수단을 통해 원하는 행동을 취할 수 없다면 다시 생각해보십시오.
이 제안은 해킹 일뿐입니다. 더 나은 방법이 있기를 바랍니다.
기본적으로, 당신은 HTML 형식의 텍스트를 가져 와서 원래의 글꼴 등을 보존하는 작은 조각으로 나누고 싶습니다. 원본 HTML을 RTF 컨트롤이나 Word 개체에로드하고 서식을 유지하는 조각으로 분할 한 다음 조각을 개별 HTML로 출력 할 수 있다고 생각합니다.
원본 HTML에서 정보를 서식 지정하여 텍스트를 추출하는 간단한 방법을 제공하는 경우 HtmlAgilityPack을 사용하는 방법이있을 수도 있습니다.