#javascript #html #xml #blob #domparser
#javascript #HTML #xml #Большой двоичный объект #domparser
Вопрос:
Я работаю с API blob-объектов в последней версии Chrome и хотел бы, чтобы следующий XML DOM был добавлен к новому пустому URL-адресу объекта:
<root>
<Title>
<H1>A Title</H1>
<H2>A Subtitle</H2>
Some text or other elements<BR/>
</Title>
</root>
Этот фрагмент XML выбирается пользователем с помощью мыши из редактируемого содержимого DIV. Затем я преобразую этот выбор в XML DOM следующим образом:
var n_parser = new DOMParser; //new parser
var small_xml_string = "<root>" window.getSelection().toString() "</root>"; //add a root node
var small_xml_obj = n_parser.parseFromString(small_xml_string.replace(/n/g, ""), "text/xml"); //convert user selection to string then to an XML DOM while removing some expected newlines below the selection
Однако DOMParser не может преобразовать в XML любые узлы, в которых были бы какие-либо теги HTML, что приводит к следующему DOM:
<root>
</Title>
</root>
Я пытался избежать HTML-объектов, но анализатор по-прежнему ведет себя так же. Это был код, который я создал, чтобы попытаться разобраться с сущностями:
var unencoded_title =
small_xml_string.toString().substring(
small_xml_string.toString().indexOf("<Title>") 7,
small_xml_string.toString().indexOf("</Title>")
);//Find the string between the title tags
var encoded_title_lt = unencoded_title.replace(/</g, "amp;<");//replace the "<" with "amp;<"
var encoded_title = encoded_title_lt.replace(/>/g, "amp;>");//replace the ">" with "amp;>"
xml_dom.getElementsByTagName("Title")[0].childNodes[0].nodeValue = encoded_title //Add the encoded string to the node, replacing what's there
Обратите внимание, что «xml_dom» — это готовый DOM, который выглядит следующим образом:
<root>
<Title>Example
</Title>
</root>
Результирующий DOM точно такой же, как если бы я передал теги HTML.
Пользователи будут добавлять HTML-теги, такие как разрывы строк и надстрочный индекс, к входным данным. Как я могу обработать HTML-теги в пользовательском вводе, готовые для передачи в api blob?
Комментарии:
1.Не могли бы вы уточнить, каким именно
window.getSelection().toString()
должно быть содержимое сейчас? Вы сказали, что пользователь выбрал весь (?) XML, который вы показали, но тогда я не понимаю, как было бы разумно, если бы вы обернули его дополнительнымroot
.2. И в какой версии HTML вы помещаете
H2
элементы orBR
вTitle
элемент? Развеtitle
обычный текст не является дочерним элементомhead
only?3. @MartinHonnen Я предполагаю, что это XML, который может содержать теги HTML, но он не должен быть HTML сам по себе.
4. Строковое значение
<root><Title><H1>A Title</H1><H2>A Subtitle</H2>Some text or other elements<BR/></Title></root>
анализируется абсолютно нормально для меня в Chrome и дает именно тот результат, который можно было бы ожидать — jsfiddle.net/53a6bed0 На самом деле не уверен, в чем на самом деле заключается проблема.5. «Проблема в том, что DOMParser не обрабатывает узлы, содержащие теги HTML» — вы так говорите , но я понятия не имею, что это на самом деле должно означать. Объясните, что не так с результатом, который я показал, или объясните, как ваш реальный сценарий на самом деле значительно отличается от того, что происходит там.
Ответ №1:
Ваша проблема заключается в getSelection().toString()
том, что это вернет текстовое содержимое фактического выбора. То, что вы хотите Range.cloneContents()
, — это получить копию структуры DOM:
document.querySelector("button").onclick = evt => {
const sel = getSelection();
const range = sel.rangeCount amp;amp; sel.getRangeAt(0);
const content = range.cloneContents?.();
const xml = new DOMParser().parseFromString(`<root>
<Title/>
</root>`, "text/xml");
xml.querySelector("Title").append(content||"");
console.log(new XMLSerializer().serializeToString(xml));
};
Select the content below:
<H1>A Title</H1>
<H2>A Subtitle</H2>
Some text or other elements<BR/>
<button>log</button>