2010-06-11 3 views
13

Я хочу иметь список требуемых элементов в любом порядке, определенном в dtd, но понятия не имею, как я мог это сделать.Требуемые элементы DTD для элементов

Например, я следующее определение:

<!ELEMENT parent (child1, child2, child3)> 

Это ОТД декларация будет успешно подтвердить следующий фрагмент XML:

<parent> 
    <child1></child1> 
    <child2></child2> 
    <child3></child3> 
</parent> 

Но в следующем случае XML не будут проходить проверку:

<parent> 
    <child2></child2> 
    <child1></child1> 
    <child3></child3> 
</parent> 

Одним из возможных решений является объявление

<!ELEMENT parent (child1 | child2 | child3)> 

Но в этом случае один из детей может отсутствовать, хотя проверка будет успешной.

Мне нужно правильное объявление элемента dtd для случая, когда список необходимых элементов может присутствовать в любом порядке.

+0

Я только что разместил этот вопрос несколько минут назад. Полностью хромает, что вы не можете переупорядочить их. – livingtech

ответ

11

ChrisF неправ, чтобы сказать, что вы не можете этого сделать (но для проверки спецификации!); DevNull [теперь известный как Daniel Haley] прав, чтобы сказать, что вы можете.

Существует, однако, одно осложнение: модель контента, заданная DevNull для , родительский нарушает правила детерминизма XML. Неформально эти правила говорят, что анализатор должен знать, не глядя, какой токен в модели контента соответствует каждому элементу в документе.Если в элементе родительский элемент синтаксический анализатор видит child1, он не может без него узнать, соответствует ли оно только первому или второму вхождению child1 в контентной модели DevNull. Это ошибка (но, как это бывает, это ошибка, которую процессоры не обязаны сообщать - это ошибка, которая означает «все ставки отключены, процессор может что-то здесь сделать, в том числе не заметить, что что-то не так»).

модель контента для родителя, который подчиняется правилам детерминизм может быть сформирована факторизуя общие префиксы, таким образом:

<!ELEMENT parent ( 
        (child1, ((child2,child3) 
          | (child3,child2))) 
       | (child2, ((child1,child3) 
          | (child3,child1))) 
       | (child3, ((child1,child2) 
          | (child2,child1))) 
       ) > 

Это менее удобно, чем декларации для этой модели может быть и на других языках схем, и для более чем трех элементов это склонно к ошибкам и крайне утомительно делать вручную. Но нельзя объявлять модель контента, которую вы хотите, с DTD. Или, может быть, я должен сказать, что это невозможно только для авторов DTD, которые не могут смириться с любыми неудобствами.

Обратите внимание также, что, если последовательность детей не несет какой-либо информации, некоторые авторитетные органы утверждают, что лучше зафиксировать последовательность.

+0

+1 для детерминированного ответа. –

2

Чтение the spec появится, вы не сможете.

Когда дети объявляются в последовательности, разделенной запятыми, дети должны отображаться в одной и той же последовательности в документе. В полной декларации дети также должны быть объявлены, а дети также могут иметь детей.

Я думаю, это потому, что вы объявляете последовательность (или упорядоченный список, если хотите), а не коллекцию (или неупорядоченный список).

+2

Er, документ, на который вы указываете, не является [спецификацией XML] (http://www.w3.org/TR/xml). –

9

Try:

<!ELEMENT parent (child1 | child2 | child3)*> 

Если позволить ноль или более любого ребенка, в любом порядке.

+0

Я не думаю, что это сработало бы, потому что это звучит так, как будто бы нужны все 3 дочерних элемента. Это основано на утверждении OP: «Но в этом случае один из дочерних элементов может отсутствовать, хотя проверка будет успешной». –

+0

Красивый ответ. Это здорово для работы с неупорядоченными элементами, о которых вы знаете, какими они будут, но не их порядком или количеством. Спасибо @ Майкл! – zeffii

2

Это сложно, если вам нужен ровно один из дочерних элементов. Это единственный способ, о котором я могу думать, и это не очень красиво. Он работает, хотя ...

<!ELEMENT parent ( 
       (child1,child2,child3)| 
       (child1,child3,child2)| 
       (child2,child1,child3)| 
       (child2,child3,child1)| 
       (child3,child1,child2)| 
       (child3,child2,child1) 
       )> 

В основном я задаю все возможные комбинации только одного элемента child1, child2 и child3.

Вот пример экземпляра. child1, child2 и child3 могут быть в любом порядке, но каждый из них должен происходить ровно один раз.

<!DOCTYPE parent [ 
<!ELEMENT parent ( 
       (child1,child2,child3)| 
       (child1,child3,child2)| 
       (child2,child1,child3)| 
       (child2,child3,child1)| 
       (child3,child1,child2)| 
       (child3,child2,child1) 
       )> 
<!ELEMENT child1 (#PCDATA)> 
<!ELEMENT child2 (#PCDATA)> 
<!ELEMENT child3 (#PCDATA)> 
]> 
<parent> 
    <child2></child2> 
    <child1></child1> 
    <child3></child3> 
</parent> 
Смежные вопросы