#javascript #node.js
Вопрос:
Я читаю XML-файл и анализирую его. Я хочу удалить width
атрибут из каждого img
элемента, который является частью XML-документа.
Как мне проанализировать этот HTML-файл, выполнить поиск тега изображения, обновить его и вернуть обновленный HTML?
Далее следует образец XML..В теге description требуется удалить img attr
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
<channel>
<title></title>
<atom:link href="" rel="self" type="application/rss xml" />
<link></link>
<description>Award-Winning Impact Media - Alt Protein amp;#38;
Sustainability Breaking News</description>
<lastBuildDate>Sun, 24 Oct 2021 19:27:36 0000</lastBuildDate>
<language>en-US</language>
<sy:updatePeriod>
hourly </sy:updatePeriod>
<sy:updateFrequency>
1 </sy:updateFrequency>
<item>
<title>Vegan .</title>
<link>https://www.google.com</link>
<dc:creator><![CDATA[Sally Ho]]></dc:creator>
<pubDate>Mon, 25 Oct 2021 00:00:00 0000</pubDate>
<category><![CDATA[Alt Protein]]></category>
<category><![CDATA[Seafood]]></category>
<category><![CDATA[Vegan]]></category>
<category><![CDATA[alternative seafood]]></category>
<category><![CDATA[plant based tuna]]></category>
<category><![CDATA[vegan seafood]]></category>
<category><![CDATA[vegan tuna]]></category>
<guid isPermaLink="false">https://www.google.com/?p=55401</guid>
<description><![CDATA[<div style="margin-
bottom:20px;">
<img width="1024" height="768" src="" class="attachment-post-
thumbnail size-post-thumbnail wp-post-image" alt="" srcset=""
sizes="
(max-width: 1024px) 100vw, 1024px" /></div>
<p><span class="rt-reading-time" style="display: block;"><span
class="rt-label rt-prefix"></span> <span class="rt-
time">4</span>
<span class="rt-label rt-postfix"> Mins Read</span></span>
</p>
<p>The post <a rel="nofollow"
href="https://www.greenqueen.com.hk/vegan-tuna-brands/"> <a
rel="nofollow" href="">Green</a>.</p>
]]></description>
</item>
Комментарии:
1. Вам нужна процедура для возврата текста или объекта, подобного дереву синтаксического анализа? Вам нужно удалять
width
атрибут из каждого тега изображения? Что представляет собой «тег изображения» — элемент HTMLimg
?2. да, вы хотите удалить атрибут width из каждого тега img
3. Из всех тегов изображений?
4. да из всех тегов img
5. Вы непоследовательны — вы говорите о XML или о HTML?
Ответ №1:
getElementsByTagName
в этом случае не будет работать, потому что html содержится в разделе CDATA (символьные данные). Содержимое этих разделов не анализируется анализатором XML и не рассматривается как разметка.
См. Ссылку на W3C:
Если они содержат HTML, самый простой способ манипулировать ими в ванильном javascript — это прочитать содержимое из nodeValue
свойства и установить его как innerHTML
свойство временного элемента, добавляемого к новому DocumentFragment . Это дает вам возможность использовать методы, обычно встречающиеся в document
для поиска элементов с использованием селекторов. ( removeWidthFromCDATA
функция в приведенном ниже фрагменте).
const xmlStr = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
<channel>
<title></title>
<atom:link href="" rel="self" type="application/rss xml" />
<link></link>
<description>Award-Winning Impact Media - Alt Protein amp;#38;
Sustainability Breaking News</description>
<lastBuildDate>Sun, 24 Oct 2021 19:27:36 0000</lastBuildDate>
<language>en-US</language>
<sy:updatePeriod>
hourly </sy:updatePeriod>
<sy:updateFrequency>
1 </sy:updateFrequency>
<item>
<title>Vegan .</title>
<link>https://www.google.com</link>
<dc:creator><![CDATA[Sally Ho]]></dc:creator>
<pubDate>Mon, 25 Oct 2021 00:00:00 0000</pubDate>
<category><![CDATA[Alt Protein]]></category>
<category><![CDATA[Seafood]]></category>
<category><![CDATA[Vegan]]></category>
<category><![CDATA[alternative seafood]]></category>
<category><![CDATA[plant based tuna]]></category>
<category><![CDATA[vegan seafood]]></category>
<category><![CDATA[vegan tuna]]></category>
<guid isPermaLink="false">https://www.google.com/?p=55401</guid>
<description><![CDATA[<div style="margin-
bottom:20px;">
<img width="1024" height="768" src="" class="attachment-post-
thumbnail size-post-thumbnail wp-post-image" alt="" srcset=""
sizes="
(max-width: 1024px) 100vw, 1024px" /></div>
<p><span class="rt-reading-time" style="display: block;"><span
class="rt-label rt-prefix"></span> <span class="rt-
time">4</span>
<span class="rt-label rt-postfix"> Mins Read</span></span>
</p>
<p>The post <a rel="nofollow"
href="https://www.greenqueen.com.hk/vegan-tuna-brands/"> <a
rel="nofollow" href="">Green</a>.</p>
]]></description>
</item>
</channel>
</rss>`;
function removeWidthFromCDATA(cdataString) {
const fragment = document.createDocumentFragment();
const html = document.createElement("div");
html.innerHTML = cdataString;
fragment.appendChild(html);
const images = fragment.querySelectorAll("img");
for (const image of images)
if (image.hasAttribute("width"))
image.removeAttribute("width");
return html.innerHTML;
}
function cleanRSS(xmlString) {
const parser = new DOMParser();
const doc = parser.parseFromString(xmlString, "application/xml");
const errorNode = doc.querySelector("parsererror");
if (errorNode) {
console.error("Error parsing xml string.")
return false;
}
const descs = doc.querySelectorAll("description");
for (const desc of descs) {
let content = desc.firstChild;
if (!content || content.nodeType !== Node.CDATA_SECTION_NODE)
continue;
content.nodeValue = removeWidthFromCDATA(content.nodeValue);
}
const serializer = new XMLSerializer();
return serializer.serializeToString(doc);
}
console.log(cleanRSS(xmlStr));
В качестве дополнительного примечания: обратите внимание на шаблон, который вы используете для создания RSS-канала. Если у вас есть контроль, вам нужно исправить отсутствующее закрытие <a>
тега в конце и обратить внимание на пробелы перед символами новой строки, потому что они прерывают имена классов CSS и свойств, применяемых к элементам внутри раздела CDATA.
Ответ №2:
Если вы можете предоставить образец ввода и вывода, мы можем расширить этот фрагмент и сделать его доступным для выполнения.
// `xml` is the xml document
const imgs = xml.getElementsByTagName("img");
for (const img of imgs) {
if (img.hasAttribute("width")) {
img.removeAttribute("width");
}
}
// output xml/html string from `xml`
Комментарии:
1. Уже пробовал это решение, но не сработало
2. Не возражаете, если опубликуете свои данные и сообщение об ошибке здесь?