#javascript #html #ajax #xml
#javascript #HTML #ajax #xml
Вопрос:
Я внутренний программист, которому поручено создать внешний элемент на сайте.
Мне нужно взять только две точки данных из внешнего XML-файла, а затем обе поместить в существующий HTML-код сайта и обновлять его каждые несколько минут.
Дерево XML большое и имеет несколько родительских элементов, мне нужны только два дочерних элемента из первого родительского элемента «Main-Library»
Вот как выглядит xml. Я сжал его так, чтобы отображался только первый дочерний элемент первых двух родителей:
<Root>
<Main-Library>
<Book>
<Title>Book Name</Title>
<Author>John Smith</Author>
<Genre>Fiction</Genre>
<Loaned>2020-09-03 13:13:48</Loaned>
<Price>-13.30</Price>
</Book>
.
.
.
</Main-Library>
<Second-Library>
<Book>
<Title>Book Name</Title>
<Author>John Smith</Author>
<Genre>Fiction</Genre>
<Loaned>2020-09-03 13:13:48</Loaned>
<Price>-13.30</Price>
</Book>
.
.
.
</Second-Library>
</Root>
Мне нужно взять Loaned и Price из первого родительского элемента Main-Library и поместить их в следующий html:
<p class="feed">
<span class="feed-text-large">Status: </span>
<span class="price">$35.98</span>
<span class="timestamp">Loaned at 13:13 on September 03, 2020</span>
</p>
с ценой и датой, поступающими из XML, и обновляющимися по мере изменения xml.
Буду признателен за любую помощь, которая поможет мне начать работу над этим. Спасибо!
Комментарии:
1. Предполагая, что структура XML никогда не меняется, вы могли попробовать использовать файл XSLT с небольшим количеством JavaScript для обновления страницы время от времени.
2. «обновление по мере изменения xml» будет непростой задачей; вам придется опросить файл и посмотреть, изменился ли он. Использование ETags поможет смягчить это, но это целая тема сама по себе….
3. Я снова открыл это, потому что вопрос, указанный как дубликат, не включает требование периодического обновления, которое, я думаю, является ключом к выбору правильного подхода.
4. @MichaelKay Повторное открытие вопроса с использованием вашего золотого значка для вопроса, на который у вас есть ответ, выходит за рамки приличия… Не говоря уже о продвижении продукта вашей компании при этом.
5. Боюсь, я не обращаю внимания на значки и тому подобное, я не знал, что для этого нужны какие-либо особые привилегии. Я просто почувствовал, что его закрытие было ошибкой, потому что в вопросе был ключевой аспект, которого не было в приведенном дубликате. Что касается того, что это мой продукт, я отвечаю на вопросы решением, которое я бы использовал, если бы у меня была проблема, независимо от того, мой это продукт или нет, в надежде, что OP сочтет это информативным.
Ответ №1:
Прежде всего — возможно ли использовать JSON? Если да, сделайте это и покажите, как данные выглядят в JSON.
Шаги, которые нужно сделать:
- Создайте функцию, которая будет извлекать данные
function getData() {
return fetch(theUrl).then(response => response.text())
}
- Создайте функцию, которая будет анализировать данные
function parseData(str) {
const data = (new window.DOMParser()).parseFromString(str, 'text/xml')
// never did anything with XML so this might be wrong
// that's why JSON would be A LOT EASIER
// this should get the first Book
const Book = data.querySelector('Root Main-Library Book')
const price = Book.querySelector('Price').innerHTML
const loaned = Book.querySelector('Loaned').innerHTML
return { price, loaned }
}
- Распечатайте данные
function printData(data) {
const priceTarget = document.querySelector('.price')
const loanedTarget = document.querySelector('.timestamp')
priceTarget.innerHTML = data.price
loanedTarget = data.loaned
}
- Создайте функцию, которая будет запускаться периодически
function update() {
getData().then(parseData).then(printData)
}
- Запустите функцию один раз и установите интервал
const minutes = 5
update()
setInterval(update, minutes * 60 * 1000) // interval in ms, so 60*1000 gets us a minute
Я не уверен на 100%, что это сработает — моя главная проблема в том parseData()
, потому что я никогда ничего не делал с XML в JavaScript.
РЕДАКТИРОВАТЬ: этот код будет считывать данные из первого элемента Book. Если вы хотите перечислить все книги, код должен быть другим. Дайте мне знать, я отвечу вам примерно через 8 часов, если никто не будет быстрее меня. Спокойной ночи
Ответ №2:
С Saxon-JS вы могли бы сделать это, запустив таблицу стилей XSLT 3.0 в следующих строках:
<xsl:template name="display">
<xsl:result-document href="#timestamp">
<xsl:text>Loaned at {/Root/Main-Library/Book/Loaned
=> translate(' ', 'T')
=> xs:dateTime()
=> format-date('[H00].[m00] on [MNn] [D1o], [Y0001]')
}</xsl:text>
</xsl:result-document>
<xsl:result-document href="#price">
<xsl:text>${/Root/Main-Library/Book/Price}</xsl:text>
</xsl:result-document>
<ixsl:schedule-action wait="60000">
<xsl:call-template name="refresh"/>
</ixsl:schedule-action>
</xsl-template>
<xsl:template name="refresh">
<ixsl:schedule-action http-request="....">
<xsl:call-template name="display"/>
</ixsl:schedule-action>
</xsl-template>
Это всего лишь набросок, иллюстрирующий идею, если вы хотите пойти по этому пути. Основное преимущество (я знаю, что некоторым это нравится больше, чем другим) заключается в том, что нет Javascript, который может ошибиться.
Отказ от ответственности: Saxon-JS — это продукт моей компании.