Создание и изменение определений типа документа
С классами DTD NSXML можно создать Определение типа документа (DTD) или обработать существующее, преобразовав его строковое представление в мелкую древовидную структуру. Можно добавить узлы, представляющие объявления DTD дереву, удалить узлы из него или изменить значения тех объявлений. Наконец, можно выписать создаваемый или измененный DTD, «встроенный» с его строковым представлением XML. Классы DTD являются NSXMLDTD и NSXMLDTDNode.
Обычно DTDs в NSXML является внутренним и установлен как свойство объекта NSXMLDocument. Когда это обрабатывает XML-документ, NSXML создает древовидную структуру DTD и присоединяет ее к документу, но только если DTD является внутренним. Однако можно создать DTD программно и выписать его к его собственному файлу (т.е. внешний DTD) использующий NSXML.
Когда NSXML обрабатывает существующий источник XML и NSXMLDocumentValidate
входная опция указана, она проверяет XML против внутреннего или внешнего DTD (см. Создание Объекта документа От Существующего XML). Однако проверка является отдельным процессом от создания древовидной структуры, представляющей DTD. (Можно также динамично проверить NSXMLDocument против его DTD путем отправки validateAndReturnError:
обменивайтесь сообщениями к объекту документа.)
Создание DTD
Если Вы читаете и обрабатываете существующий источник XML использование интерфейсов NSXML, и что XML включает внутренний DTD, мелкое (двухуровневое) дерево создается для представления DTD. В корне этого дерева экземпляр класса NSXMLDTD; этот объект имеет дочерние элементы, состоящие из объектов узлов NSXMLDTDNodeDTD, каждый представляющий объявление для элемента, объекта, списка атрибутов или нотации в DTD. (Дочерние элементы могут также включать объекты NSXMLNode, представляющие комментарии и обрабатывающие инструкции, найденные в источнике DTD.), Поскольку это анализирует объявления и создает узлы DTD, NSXML устанавливает вид (NSXMLNodeKind
) и подвид DTD (NSXMLDTDNodeKind
) из каждого создаваемого узла.
Можно также создать автономный объект NSXMLDTD из внешнего DTD с initWithContentsOfURL:options:error:
или initWithData:options:error:
методы. Тогда можно связать этот объект DTD с объектом XML-документа через setDTD:
метод класса NSXMLDocument.
Создаваемое дерево DTD связано с XML-документом как свойство. В программируемых условиях это означает, что можно получить доступ к объекту NSXMLDTD (и его дочерние элементы NSXMLDTDNode) путем отправки NSXMLDocument возражают a DTD
сообщение. Как только Вы получили доступ к объекту NSXMLDTD, можно добавить дочерние элементы, удалить дочерние элементы, объявления изменения, и т.д. (см. Изменение DTD).
Можно также создать полностью новое дерево DTD программно. Для этого завершите следующие шаги:
Создайте экземпляр класса NSXMLDTD.
Если DTD должен быть внешним, установите его систему ID (
setSystemID:
) и, при необходимости, его общедоступный ID (setPublicID:
).Создайте экземпляры класса NSXMLDTDNode для каждого объявления, которое Вы хотите в DTD. Для создания этих объектов, можно использовать
initWithXMLString:
метод класса NSXMLDTDNode, метода класса NSXMLNodeDTDNodeWithXMLString:
, или NSXMLNodeinitWithKind:
метод. Первые два из этих методов берут строку, эквивалентную объявлению DTD, например<!ELEMENT name (#PCDATA)>
(Если Вы используете
initWithKind:
метод, необходимо установить строку, или объектное значение узла DTD соответственно — посмотрите Изменение DTD.) Каждый создал узел DTD, автоматически присваивается вид узла (если Вы явно не присваиваетесь), и подвид DTD, на основе проанализированного объявления. Можно повторно присвоить подвид сsetDTDKind:
метод.Добавьте, что каждый создал объект NSXMLDTDNode к объекту NSXMLDTD как дочерний элемент (использование
addChild:
илиinsertChild:atIndex:
).Для больше на создании, добавление и иначе управление дочерними элементами объекта NSXMLDTD, видят Изменение DTD.
Как только Вы создали DTD, необходимо решить, должно ли это быть внутренним или внешним DTD. Если внутренний DTD, присоедините его к объекту NSXMLDocument использование setDTD:
метод. Когда Вы выписываете XML-документ, строковое представление DTD кажется встроенным в XML. Если DTD является внешним, не присоединяйте его к NSXMLDocument, но выписывайте его отдельно, как проиллюстрировано в Перечислении 1.
Перечисление 1 , Создающее внешний DTD
- (void)createExternalDTD { |
NSXMLDTD *theDTD = [[[NSXMLDTD alloc] init] autorelease]; |
[theDTD setSystemID:@"http://www.boggle.com/DTDs/index.html"]; |
NSXMLDTDNode *attrNode = [[[NSXMLDTDNode alloc] initWithXMLString: |
@"<!ATTLIST phone location (home | office | mobile) 'home'>"] |
autorelease]; |
NSXMLDTDNode *elemNode = [[[NSXMLDTDNode alloc] initWithXMLString: |
@"<!ELEMENT address (street1, street2, city, state, zip)>"] |
autorelease]; |
NSXMLDTDNode *entNode = [[[NSXMLDTDNode alloc] initWithXMLString: |
@"<!ENTITY % children 'first, middle, last'>" ] |
autorelease]; |
NSString *thePath = [self savePath]; // custom method |
[theDTD addChild:attrNode]; |
[theDTD addChild:elemNode]; |
[theDTD addChild:entNode]; |
[[theDTD XMLString] writeToFile:thePath atomically:YES]; |
} |
Изменение DTD
Как с изменением XML-документа, можно изменить DTD двумя общими способами. Можно изменить структуру дерева, представляющего DTD путем добавления, удалив и заменив узлы. И можно изменить значение узлов DTD, по существу изменив объявление.
Когда Вы изменяете значение использования объектов NSXMLDTDNode setStringValue:
или setObjectValue:
какие изменения зависит от типа объявления:
Если тип смешан или объявление элемента, строка проверки изменяется. Например, в объявлениях
<!ELEMENT title (#PCDATA)*>
<!ELEMENT item (head, (p | list | note))>
(#PCDATA)*
и(head, (p | list | note))
строки проверки.Если тип является объектом, изменениями значения объекта. В объявлении
<!ENTITY foo “bar”>
“bar”
значение объекта.Если тип является объявлением списка атрибутов, изменениями значения по умолчанию. В объявлении
<!ATTLIST bar foo (moo | boo) “moo”>
“moo”
значение по умолчанию.Нотации не имеют никакого изменяемого значения.
Методы NSXMLDTD для управления структурой DTD являются следующим:
- (void)insertChild:(NSXMLNode *)child atIndex:(unsigned)index
- (void)insertChildren:(NSArray *)children atIndex:(unsigned)index
- (void)replaceChildAtIndex:(unsigned)index withNode:(NSXMLNode *)node
Эти методы, которые идентичны в подписи и цели к методам NSXMLDocument и NSXMLElement, имеют однозначные использования. Все они кроме removeChildAtIndex:
потребуйте, чтобы Вы для создания NSXMLDTDNode возразили сначала (или отсоединились, существующий NSXMLDTDNode возражают сначала). Как кратко обсуждено в Создании DTD, Вы обычно создаете объект NSXMLDTDNode с initWithXMLString:
метод или DTDNodeWithXMLString:
или initWithKind:
методы класса NSXMLNode. Параметром первых двух методов является объект NSString представление объявления DTD, как показано в этом примере:
NSXMLDTDNode *attrNode = [[[NSXMLDTDNode alloc] initWithXMLString: |
@"<!ATTLIST phone location (home | office | mobile) 'home'>"] |
autorelease]; |
Обратите внимание на то, что можно также создать и добавить дочерние элементы к объекту NSXMLDTD, которые являются объектами NSXMLNode, представляющими комментарии и обрабатывающими инструкции.
Нахождение объявления для конструкции XML
При реализации собственной схемы динамической проверки XML необходимо знать, какое объявление DTD управляет размещением, формой и допустимыми значениями определенной конструкции XML. Следующие удобные методы NSXMLDTD предоставляют Вам ту информацию:
- (NSXMLDTDNode *)entityDeclarationForName:(NSString *)name
- (NSXMLDTDNode *)elementDeclarationForName:(NSString *)name
- (NSXMLDTDNode *)attributeDeclarationForName:(NSString *)name elementName:(NSString *)elementName
- (NSXMLDTDNode *)notationDeclarationForName:(NSString *)name
Вы предоставляете этим методам имя объекта, элемента, нотации и атрибута (плюс, для атрибутов, имени элемента), и они возвращают NSXMLDTDNode, управляющий конструкцией XML.
Также Вы могли получить дочерние элементы объекта NSXMLDTD и проанализировать их.