Использование связывания данных по одной записи

Связывание данных по одной записи используется для HTML-элементов, которые не являются таблицами и не включены в связанную таблицу. HTML-элемент - например, SPAN, BUTTON или LABEL - связывается с отдельным полем XML. После этого HTML-элемент автоматически отображает содержимое поля XML, с которым он связан (сцеплен). Например, следующий HTML-элемент SPAN сцеплен с полем TITLE XML-документа, доступ к которому осуществляется через фрагмент данных dsoBoofc:

<SPAN DATASRC="#dsoBook" DATAFLD="TITLE"></SPAN>

Поскольку HTML-элемент не имеет множественных частей, подобно таблице, он способен отобразить значение поля только для одной записи за раз. Чтобы использовать связывание данных по одной записи, XML-до-кумент должен быть организован как простой набор записей. (См. раздел «Использование одной HTML-таблицы для отображения простого набора записей» в начале этой главы.)

Наипростейшим случаем связывания данных по одной записи является случай, когда XML-документ состоит только из одной записи, подобно документу из Листинга 8-7. (Копия этого листинга содержится на прилагаемом к книге CD-ROM в файле Book.xml.)

Листинг 8-7

Book.xml

<?xmlversion="1.0"?>

<!-- Имя файла: Book.xml -->

<BOOK>

<ТIТLЕ>Тпе Adventures of Huckleberry Finn</TITLE> 

<AUTHOR>Mark Twain</AUTHOR> 

<BINDING>mass market paperback</BINDING> 

<PAGES>298</PAGES> 

<PRICE>$5.49</PRICE>

</BOOK>

В Листинге 8-8 представлена HTML-страница, которая связывает отдельный элемент SPAN с каждым из полей рассматриваемого документа (TITLE, AUTHOR, BINDING, PAGES, PRICE). (Копия этого листинга содержится на прилагаемом к книге CD-ROM в файле Book.htm.)

Листинг 8-8

Book.htm

<!-- Имя файла: Book.htm --> 

<HTML>

<HEAD>

<TITLE>Book Description</TITLE> 

</HEAD>

<BODY>

<XML ID="dsoBook" SRC="Book.xml"></XML> 

<H2>Book Description</H2>

<SPAN STYLE="font-style:italic">Title:</SPAN> 

<SPAN STYLE="font-weight:bold" DATASRC="#dsoBook"

DATAFLD="TITlE"></SPAN> 

<BR>

<SPAN STYLE="font-style:italic">Author: </SPAN> 

<SPAN DATASRC="#dsoBook" DATAFLD="AUTHOR"></SPAN> 

<BR>

<SPAN STYLE="font-style:italic">Binding type:</SPAN> 

<SPAN DATASRC="#dsoBook" DATAFLD="BINDING"></SPAN>  

<BR>

<SPAN STYLE="font-sty!e:italic">Number of pages:</SPAN>

<SPAN DATASRC="#dsoBook" DATAFLD="PAGES"></SPAN>

<BR>

<SPAN STYLE="font-style:italic">Price:</SPAN>

<SPAN DATASRO"#dSOBook" DATAFLD="PRICE"></SPAN>

</BODY> 

</HTML>

На следующем рисунке показано, как Internet Explorer 5 отобразит эту страницу.

Перемещение между записями

Если XML-документ содержит более одной записи (как обычно бывает), связывание данных по записям становится несколько более сложным, поскольку HTML-элемент может отобразить зараз только одну запись. Отображаемая в данный момент запись называется текущей записью. (Связывание данных по одной записи иногда называют еще связыванием по текущей записи.) Изначально текущей является первая запись в документе.

DSO (объект исходных данных), ассоциированный с XML-документом, предоставляет ряд методов (функций), которыми вы можете воспользоваться при перемещении между записями. Эти методы принадлежат объекту recordset DSO и приведены в таблице 8.2. Заметим, что примеры вызовов, приведенные в последнем столбце, предполагают, что HTML-страница содержит фрагмент данных XML с идентификатором (ID) dsolnventory.

Таблица 8.2

Метод объекта recordset DSO

moveFirst

Переход от текущей записи к

первой записи в документе

Пример вызова

dsolnventory.recordset.moveFirst()

movePrevious

предыдущей записи

dsolnventory.recordset.movePrevious()

moveNext

следующей записи

dsolnventory.recordset.moveNext()

moveLast

последней записи в документе

dsolnventory.recordset.moveLast()

move

записи с указанным номером

dsolnventory.recordset.move(5) (Переход к пятой записи. Записи нумеруются, начиная с нуля)

Примечание. Составной объект recordset DSO соответствует стандарту технологии доступа к данным, которую Microsoft назвала ActiveX Data Objects (ADO). Вы можете использовать объект общего назначения ADO recordset совместно с множеством различных источников данных, а не только с XML DSO. Более подробную информацию об ADO и объекте ADO recordset вы можете найти на Web-сайте Microsoft по адресу http:// www.microsoft.com/data/ado/default.htm. За документацией по методам, свойствам и событиям объекта recordset обращайтесь по адресу: http://msdn.microsoft.com/library/psdk/dasdk/mdap2y7s.htm.

Вы можете обращаться к этим методам из написанного вами кода сценария. Однако самый простой способ их вызова - это присвоить имя метода атрибуту ONCLICK элемента BUTTON, как в следующем примере:

<BUTTONONCUCK="dsolnventory.recordset.moveFirst()">

First Record 

</BUTTON>

Этот элемент отображает кнопку. Когда пользователь щелкает мышью на кнопке, вызывается метод, присвоенный атрибуту ONCLICK, dsolnventory. recordset.moveFirst.

Если текущей является первая запись, вызов метода movePrevious приводит к перемещению в зону начала файла (BOF), где нет записей, поэтому сцепленный элемент будет пуст. Аналогично, вызов метода moveNext, если текущей является последняя запись, приводит к перемещению в зону конца файла (EOF), поэтому сцепленный элемент также будет пуст.

К счастью, объект recordset поддерживает свойство BOF, которое принимает значение true (истина), если достигнуто начало файла, а также свойство EOF, которое принимает значение true (истина), если достигнут конец файла. Вы можете использовать эти свойства для определения этих состояний и внесения необходимых корректировок. Например, приведенный ниже код предписывает при щелчке на кнопке в случае, если достигнуто начало файла, быстро отобразить первую запись:

<BUTTONONCLICK="dsolnventory.recordset.movePrevious();

if (dsolnventory.recordset.BOF)

dsolnventory.recordset.moveNext()"> 

Back 

</BUTTON>

Следующий код проверяет достижение конца файла:

<BUTrONONCUCK="dsolnventory.recordset.moveNext();

if (dsolnventory.recordset.EOF)

dsolnventory.recordset.movePrevious()"> 

Forward 

</BUTTON>

Обратим внимание, что вы можете присвоить атрибуту ONCLICK (либо другим атрибутам, относящимся к событиям, например, ONMOUSEOVER) целый блок кода сценария. В этих примерах код написан на языке Microsoft JScript. Далее в этой главе вы узнаете, как писать самостоятельные фрагменты кодов сценариев, которые позволяют включать значительно большее число инструкций.

В следующем упражнении вы создадите HTML-страницу, которая отображает XML-документ из Листинга 8-3 по одной записи за один раз. Страница содержит кнопки для перехода к первой, предыдущей, последующей и последней записям.

Отобразите документ по отдельным записям

  1. Откройте новый, пустой текстовый файл в вашем текстовом редакторе и введите содержимое HTML-страницы, представленное в Листинге 8-9. (Копия этого листинга содержится на прилагаемом к книге CD-ROM в файле Inventory Single.htm.) Обратите внимание, что страница содержит фрагмент данных, который связан с документом Inventory Big.xml, содержащим 16 записей. (См. Листинг 8-3 и файл на CD-ROM.)
  2. Воспользуйтесь командой Save (Сохранить) вашего текстового редактора, чтобы сохранить страницу на вашем жестком диске, присвоив ей имя файла lnventorySingle.htm.

Листинг 8-9

Inventory Single.htm

<!-- Имя файла: Inventory Single.htm --> 

<HTML>

<HEAD>

<TITLE>Book lnventory</TITLE> 

</HEAD> 

<BODY>

<XML ID="dsolnventory" SRC="Inventory Big.xml"></XML> 

<H2>Book Description</H2>

<SPAN STYLE="font-style:italic">Title:</SPAN> 

<SPAN DATASRC="#dsolnventory" DATAFLD="TITLE"

STYLE="font-weight:bold"></SPAN> 

<BR>

<SPAN STYLE="font-style:italic">Author:</SPAN> 

<SPAN DATASRC="#dsolnventory" DATAFLD="AUTHOR"></SPAN> 

<BR>

<SPAN S7YLE="ront-style:italic">Binding type:</SPAN> 

<SPAN DATASRC="#dsolnventory" DATAFLD="BINDING"></SPAN> 

<BR>

<SPAN S7YLE="font-style:italic">Number of pages:</SPAN> 

<SPAN DATASRC="#dsolnventory" DATAFLD="PAGES"></SPAN > 

<BR>

<SPAN STYLE="font-style:italic">Price: </SPAN> 

<SPAN DATASRC="#dsolnventory" DATAFLD="PRICE"></SPAN>

<HR>

<BUTTON ONCLJCK="dsolnventory.recordset.moveFirst()">

|&lt; First 

</BUHON>

<BUTTON ONCLICK="dsolnventpry.recordset.movePrevious(); 

if (dsolnventory.recordsqt.BOF) 

dsolnventory.recordset.moveNext()"> 

&lt; Back 

</BUTTON>

<BUTTON ONCUCK="dsolnventory.recordset.moveNext(); 

if (dsolnventory.recordset.EOF) 

dsolnventory.recordset.movePrevious()"> 

Forward &gt; 

</BUTTON> 

<BUTTONONCUCK="dsolnventory.recordset.moveLast()">

Last &gt;| 

</BUTTON>

</BODY>

</HTML>

  1. В Windows Explorer (Проводник) или в окне папки дважды щелкните на имени файла Inventory Single.htm, который вы сохранили на предыдущем шаге. Internet Explorer 5 откроет страницу и отобразит ее, как показано на следующем рисунке.

Заметим, что изначально, пока пользователь еще не щелкнул мышью на какой-либо кнопке, Internet Explorer 5 отображает только первую запись в документе.

Другие способы связывания данных

В последующих разделах вы познакомитесь с рядом других способов для связывания не табличных HTML-элементов. Это могут быть как индивидуальные HTML-элементы, используемые для связывания данных по одной записи, так и HTML-элементы, содержащиеся в сцепленной таблице HTML. Конкретно вы узнаете:

В таблице 8.3 сведена важная информация, которая вам потребуется при изучении материала последующих разделов. В ней содержатся HTML-элементы, которые вы можете использовать для связывания данных по одной записи - т.е., все сцепляемые HTML-элементы, за исключением элемента TABLE. Для каждого элемента описано его назначение, указано свойство элемента, через которое он сцепляется с полем XML, указано, может ли элемент передавать HTML-разметку, содержащуюся в поле XML, с которым он сцеплен, а также может ли элемент обновлять содержимое поля XML. Эта информация не будет сколько-нибудь значимой для вас, пока вы не изучите последующие разделы, но позднее вы можете вернуться к этой таблице и пользоваться ею как справочной.

Таблица 8.3. Сцепляемые HTML-элементы (за исключением элемента TABLE)

HTML-элемент

Назначение элемента

Свойство (или свойства) для сцепления элемента

Передает ли разметку HTML, содержащуюся в поле XML?

Обновляет ли сцепленное поле XML?

А

Элемент «якорь»; указывает на начало или место назначения гиперссылки

href

Нет

Нет

APPLET

Добавляет на страницу фрагмент кода Java

раrаm

Нет

Да

BUTTON

Отображает кнопку управления

innerHTML и innerText

Да

Нет

DIV

Используется для форматирования части документа, такой как глава, раздел или приложение

innerHTML и innerText

Да

Нет

FRAME

Содержит отдельный фрейм (кадр) в наборе фреймов

src

Нет

Нет

IFRAME

Создает не выделенный обтекаемый фрейм

src

Нет

Нет

IMG

Отображает рисунок или видеоклип

src

Нет

Нет

INPUT TUPE= CHECKBOX

Отображает поле флажка в форме

checked

Нет .

Да

INPUT TUPE= HIDDEN

Хранит и предоставляет информацию на сервер, вместо отображения в форме

value

Нет

Да

INPUT TUPE= PASSWORD

АналогичноШРиТ TYPE=TEXT, но вводимый пользователем текст не отображает

value

Нет

Да

INPUT TUPE= RADIO

Отображает в форме радио-кнопку

checked

Нет

Да

INPUT TUPE=TEXT

Разрешает пользователю ввести однострочный текст в форме

value

Нет

Да

LABEL

Отображает текстовую надпись (этикетку)

innerText и innerHTML

Да

Нет

MARQUEE

Отображает текст с прокруткой

innerText и innerHTML

Да

Нет

SELECT

Отображает поле списка

свойство text для выбранного элемента списка

Нет

Да

SPAN

Используется для форматирования фрагмента текста (например, текста внутри элемента Р [абзац] или DIV)

innerText и innerHTML

Да

Нет

TEXTAREA

Разрешает пользователю вводить многострочный текст

value

Нет

Да

 

Связывание с другими HTML-элементами

При связывании элемента SPAN с полем XML элемент просто отображает содержимое поля. Это происходит потому, что свойство innerText элемента SPAN, которое определяет текст, отображаемый элементом, сцеплено с полем XML.

Примечание. В DHTML, поддерживаемом Internet Explorer 5, каждый HTML-элемент обладает набором свойств, которые вы можете использовать для установки или извлечения различных характеристик элемента с помощью кода сценария. Кроме того, для свойства автоматически устанавливается значение поля XML, с которым оно сцеплено.

Однако, как видно из таблицы 8.3, для некоторых сцепляемых HTML-элементов с полем XML сцепляются и другие свойства.

Примечание. При связывании с элементом SPAN реально сцепляются его свойства innerText и innerHTML. Свойство inner-Text устанавливает или получает текстовое содержимое элемента, не включая в него HTML-разметку. Свойство innerHTML устанавливает или получает полное содержимое элемента, включая любую HTML-разметку.

Например, для следующего сцепленного элемента А (элемент «анкер», используемый для создания гиперссылок) свойство href сцеплено с полем XML:

<А DATASRC="dsolnventory" DATAFLD="REVIEWS">

Click here for reviews 

</A>

Это свойство, как и атрибут HREF элемента, устанавливает URL для гиперссылки. Следовательно, из поля XML извлекается URL гиперссылки для сцепленного элемента А, а не его текстовое содержимое. (XML-поле REVIEWS в рассматриваемом примере должно содержать корректный URL.)

В качестве другого примера рассмотрим связывание поля флажка элемента INPUT через свойство checked (которое изменяет статус выбора элемента (установлен или сброшен флажок)) с XML-полем:

<INPUTTYPE="CHECKBOX" DATASRC="#dsolnventory" DATAFLD="INSTOCK">

Если XML-поле INSTOCK пусто, либо содержит текст "0" или "false", то поле флажка очищается. Если оно содержит какой-либо другой текст, флажок устанавливается.

В качестве последнего примера рассмотрим элемент IMG (изображение), свойство src которого сцеплено с XML-полем. Это свойство, как и атрибут SRC элемента, задает URL файла, содержащего графические данные. Листинги 8-10 и 8-11 иллюстрируют технику сцепления для элемента

IMG. (Копии этих листингов содержатся на прилагаемом к книге CD-ROM в файлах Inventory Image.xml и Image Table.htm.)

Листинг 8-10

Inventory Image.xml

<?xml version="1.0"?>.

<!-- Имя файла: Inventory lmage.xml -->

<INVENTORY> 

<BOOK>

<COVERIMAGE>Leaves.bmp</COVERIMAGE>

<TITLE>Leaves of Grass<7TITLE>

<AUTHOR>Walt Whitman</AUTHOR>

<BINDING>hardcover</BINDING>

<PAGES>462</PAGES>

<PRICE>$7.75</PRICE> 

</BOOK> 

<BOOK>

<COVERIMAGE>Legend.bmp</COVERIMAGE>

<TITLE>The Legend of Sleepy Ноllоw<\TITLE>

<AUTHOR>Washingtonlrving</AUTHOR>

<BINDING>mass market paperback</BINDING>

<PAGES>98</PAGES>

<PRICE>$2.95</PRICE> 

</BOOK> 

<BOOK>

<COVERIMAGE>Moby.bmp</COVERIMAGE>

<TITLE>Moby-Pick<AITLE>

<AUTHOR>Herman Melville</AUTHOR>

<BINDING>hardcover</BINDING>

<PAGES>724</PAGES>

<PRICE>$9.95</PRICE> 

</BOOK> 

</INVENTORY>

 

Листинг 8-11

Inventory Image Table.htm

<!-- Имя файла: Inventory Image Table.htm -->

<HTML>

<HEAD>

<TITLE>Book lnventory</TITLE> 

</HEAD>

<BODY>

<XML ID="dsolnventory" SRC="lnventory lmage.xml"></XML> 

<H2>Book lnventory</H2>

<TABLE DATASRC="#dsolnventory" BORDER="1" CELLPADDING="5"> 

<THEAD>

<TH>Cover</TH>

<TH>Title</TH>

<ТН>Author</TH>

<TH>Binding</TH>

<ТН>Pages</TH>

<ТН>Price</TH> 

</THEAD> 

<TR AUGN="center">

<TD><IMG DATAFLD="COVERIMAGE"></TD>

<TD><SPAN DATAFLD="TITLE"

STYLE="font-styte:italic"></SPAN></TD>

<TD><SPAN DATAFLD="AUTHOR"></SPAN></TD>

<TD><SPANDATAFLD="BINDING"></SPAN></TD>

<TD><SPAN DATAFLD="PAGES"></SPAN></TD>

<TD><SPAN DATAFLD="PRICE></SPAN></TD> 

</TR>

</TABLE>

</BODY> 

</HTML>

Листинг 8-10 есть XML-документ, который содержит поле с именем COVERIMAGE в каждой записи BOOK. Каждое поле COVERIMAGE содержит URL графического файла, который хранит рисунок обложки книги. Листинг 8-11 - это та же самая HTML-страница, что и в Листинге 8-2, за исключением того, что в начало каждой строки таблицы добавлена дополнительная ячейка (элемент TD), которая содержит элемент IMG, а не SPAN. Элемент IMG сцеплен с полем COVERIMAGE XML-документа, и поэтому отобразит рисунок обложки для каждой книги, как показано на следующем рисунке.

Вы можете поэкспериментировать со связыванием некоторых других HTML-элементов, содержащихся в таблице 8.3, чтобы познакомиться с их сцепляемыми свойствами и способами использования элементами данных, предоставляемых XML-полями, с которыми они сцеплены.

Передача HTML-разметки

По умолчанию, если символьные данные XML-поля включают HTML-разметку, HTML-элемент, сцепленный с этим полем, воспринимает и отображает символы разметки как литерал. Рассмотрим, например, следующий элемент SPAN, который сцеплен с XML-полем AUTHOR-BIO:

<SPAN DATASRC="#dsolnventory" DATAFLD="AUTHOR-BIO"></SPAN>

Если поле AUTHOR-BIO содержит элемент I (курсив), например:

<AUTHOR-BIO>Henry James was an American author who lived from 1843to 1916, 

and wrote &lt;l>The Bostonians&lt;l> and many other works of psychologically realistic fiction.</AUTHOR-BIO>

элемент SPAN, который воспринимает символы HTML-разметки как литералы, отобразит содержимое поля следующим образом:

Henry James was an American author who lived from 1843 to 1916, and wrote 

<I>The Bostonians </!> and many other works of psychologically realistic fiction.

Для некоторых сцепляемых HTML-элементов, таких как SPAN, вы можете установить для атрибута DATAFORMATAS значение «HTML», что заставит браузер обрабатывать любую HTML-разметку, содержащуюся в тексте поля, а не просто воспринимать ее как символы-литералы. Предположим, вы определили рассмотренный ранее элемент SPAN следующим образом:

<SPAN DATASRC="tdsolnventory" DATAFLD="AUTHOR-BIO" 

DATAFORMATAS="HTML"></SPAN>

Текст внутри элемента I будет воспринят как текст с курсивным начертанием:

Henry James was an American author who lived from 1843 to 1916, and wrote 

The Bostonians and many other works of psychologically realistic fiction.

Примечание. Присвоение атрибуту DATAFORMATAS его значения по умолчанию, «TEXT», дает тот же эффект, что и пропуск этого атрибута -символы HTML-разметки будут восприниматься как литералы.

Чтобы узнать, какие элементы вы можете использовать для передачи HTML-разметки посредством установки атрибута DATAFORMATAS="HTML", обратитесь к таблице 8.3. Для таких элементов в предпоследнем столбце таблицы («Передает ли разметку HTML, содержащуюся в поле XML?») стоит «Да».

Вставка и передача HTML-разметки в XML-поля весьма полезна для изменения формата части текста (например, с использованием элементов I или В) и для включения HTML-элементов, таких как гиперссылки или изображения, в текст. Хотя форматирование XML-текста путем включения в XML HTML-разметки нарушает принцип разделения данных и форматов, при связывании данных эта техника является единственным подходящим способом модификации формата или включения HTML-элементов внутрь поля. (При использовании других методов отображения XML, рассматриваемых в этой книге, вы обычно имеете возможность форматировать или вставлять элементы внутрь XML-элемента путем включения дочерних элементов и соответствующей их обработки.)

Когда вы добавляете HTML-разметку в XML-поле, вы не можете помещать в текст символ левой угловой скобки (<) или знак амперсенда (&) как литералы. (Напомним, что эти символы недопустимы в символьных данных элемента.) Однако вы можете вставлять их с использованием предопределённых ссылок на примитивы &lt; и &атр;. Другой возможностью сделать HTML-разметку более наглядной, что особенно полезно для большого фрагмента HTML, является использование разделов CDATA (см. главу 4).

Обновление накопленных данных XML

Объект DSO XML дает вам возможность модифицировать данные XML несколькими способами. Прежде, чем начать применять эту возможность, следует представлять, что при этом модифицируется только копия данных XML, которую DSO временно хранит в памяти, а не оригинальный XML-документ на сервере. Если вы не используете известные способы обновления оригинального документа на сервере (они не рассматриваются в этой книге), обновление одних лишь накопленных данных XML несет мало пользы.

Вы можете разрешить пользователю модифицировать определенное XML-поле, сцепив его с HTML-элементом, допускающим обновление, например, элемент INPUT типа TEXT. В крайнем правом столбце таблицы 8.3 содержатся сведения, допускает ли HTML-элемент обновление пользователем XML-поля, сцепленного с этим элементом.

Например, если вместо сцепления поля TITLE с элементом SPAN вы свяжете его с элементом INPUT типа TEXT, как показано ниже, пользователь сможет редактировать, а не только просматривать, содержимое TITLE:

<INPUT TYPE="ТEXT" DATASRC="#dsolnventory" DATAFLD="TITLE">

Кроме того, объект recordset DSO предоставляет методы, которые позволяют вам добавлять или удалять целые записи из накопленного набора записей, а также отменять модификацию записей. Эти методы сведены в таблицу 8.4. Заметим, что для примеров в последнем столбце предполагается, что HTML-страница содержит фрагмент данных XML с идентификатором (ID) dsolnventory.

Таблица 8.4

Метод объекта recordset DSO

Эффект

Пример обращения

addNew

Добавляет новую запись к накопленному набору записей

dsolnventory.recordset.addNew()

delete

Удаляет текущую запись из накопленного набора записей

dsolnventory.recordset.deleteQ

cancelUpdate

Возвращает любые изменения, сделанные для полей текущей записи, либо удаляет вновь введенную запись

dsolnventory.recordset.cancelllpdate()

Использование DTD при связывании данных

Все рассматриваемые ранее в этой главе документы были корректно сформированными XML-документами без объявления типа документа (DTD). Однако в случае, если вы собираетесь отображать XML-документ с использованием связывания данных, включение DTD и превращение документа в валидный поможет вам обеспечить требуемую симметричность организации набора записей при определении элементов докуме