Одна XML-схема для нескольких, но похожих XML-файлов - PullRequest
1 голос
/ 22 марта 2009

Как я могу создать одну XML-схему, которая будет работать с несколькими, но похожими XML-файлами. Например, для веб-сайта Food Recipes у меня есть XML-рецепт под названием «десерт», другой «индийский» и еще один «вегетарианский», все они в значительной степени одинаковы, единственное, что меняется, - это корневой элемент. Вот пример файла:

<?xml version="1.0" encoding="utf-8"?>
<!-- this one could be dessert, indian or vegetarian -->
<dessert id="dessert01" xmlns="http://www.w3schools.com"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="schematize.xsd">
    <category>Dessert</category>
    <headline>Caramelised Bananas and Puff Pastry</headline>
    <thumbnail>http://media.lookandtaste.com/files/video_thumbs/caramelized_banana_on_puff_pastry.jpg</thumbnail>
    <intro>Most people are terrified of making desserts so this is one
    that I invented to get you all out of that tricky situation...</intro>
    <media>
        <video><![CDATA[
        <object type="application/x-shockwave-flash" data="http://www.lookandtaste.com//web/jwplayer/player.swf" width="480" height="292" ><param name="movie" value="http://www.lookandtaste.com//web/jwplayer/player.swf" /><param name="bgColor" value="#000000" /><param name="allowfullscreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="FlashVars" value="stretching=exactfit&file=http://videos.lookandtaste.com/New_Vids/Caramelised Bananas and Puff Pastry_01.flv&image=http://www.lookandtaste.com/files/video_thumbs/caramelized_banana_on_puff_pastry.jpg"/></object>
     ]]>
        </video>
    </media>
    <summary>
        <preparation>10 minutes</preparation>
        <time>20 minutes</time>
        <difficulty>Medium</difficulty>
        <healthy>2</healthy>
    </summary>
    <ingredients>
        <ingredient>Puff pastry</ingredient>
        <ingredient>Bananas</ingredient>
        <ingredient>12 cups of sugar</ingredient>
        <ingredient>Knob of butter</ingredient>
        <ingredient>2 tsp of creme fraiche</ingredient>
        <ingredient>1/2 cup of chocolate</ingredient>
    </ingredients>
    <procedures>
        <step>Peel the bananas and chop into chunks. Put the butter and
        bananas in a pan over a medium heat and sprinkle with sugar.
        Caramelise for 4-5 minutes moving the ingredients every few minutes.</step>
        <step>Meanwhile sprinkle flour onto a baking tray and also
        onto a clean flat surface. Roll your pastry on the surface and then
        cut out a circle shape using the top of a bowl as a cutter.</step>
        <step>Put the pastry on the floured baking tray and prick the
        pastry with a fork. Put the pastry into the over for 12-15 minutes at
        180c/360f.</step>
        <step>The bananas should be caramelised now so take them off the
        heat and set them aside.</step>
        <step>Take the pastry out of the oven once it is ready and pile
        the bananas on top with some creme fraiche. Drizzle with melted
        chocolate and serve.</step>
    </procedures>
    <keywords>banana hot caramel dessert</keywords>
</dessert>

... А вот мой файл XML-схемы:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified">
    <xs:element name="dessert">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="category"/>
                <xs:element ref="headline"/>
                <xs:element ref="thumbnail"/>
                <xs:element ref="intro"/>
                <xs:element ref="media"/>
                <xs:element ref="summary"/>
                <xs:element ref="ingredients"/>
                <xs:element ref="procedures"/>
                <xs:element ref="keywords"/>
            </xs:sequence>
            <xs:attribute name="id" use="required" type="xs:NCName"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="category" type="xs:NCName"/>
    <xs:element name="headline" type="xs:string"/>
    <xs:element name="thumbnail" type="xs:anyURI"/>
    <xs:element name="intro" type="xs:string"/>
    <xs:element name="media">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="video"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="video" type="xs:string"/>
    <xs:element name="summary">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="preparation"/>
                <xs:element ref="time"/>
                <xs:element ref="difficulty"/>
                <xs:element ref="healthy"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="preparation" type="xs:string"/>
    <xs:element name="time" type="xs:string"/>
    <xs:element name="difficulty" type="xs:NCName"/>
    <xs:element name="healthy" type="xs:integer"/>
    <xs:element name="ingredients">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" ref="ingredient"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="ingredient" type="xs:string"/>
    <xs:element name="procedures">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" ref="step"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="step" type="xs:string"/>
    <xs:element name="keywords" type="xs:string"/>
</xs:schema>

Буду очень признателен за указание на возможное решение или на то, как приблизиться к нему. Заранее спасибо!

Ответы [ 4 ]

2 голосов
/ 22 марта 2009

Разве это не просто:

<xs:complexType name="food">...</xs:complexType>
<xs:element type="food" name="dessert"/>
<xs:element type="food" name="indian"/>
1 голос
/ 22 марта 2009

При написании схемы для корневого элемента необходимо указать индикатор «выбор». Поскольку большая часть содержимого является общей для всех корневых элементов, вы можете определить один сложный тип и затем использовать его повторно, чтобы избежать их повторной записи. См. http://www.w3schools.com/schema/schema_complex_indicators.asp

[EDIT]

Если вы можете контролировать структуру документа XML (т.е. если они не используются другими приложениями), почему бы не определить корневой элемент с именем «food» и указать возможный атрибут foodType со значениями, такими как «desert» и «indian» .

0 голосов
/ 22 марта 2009

А как насчет Кульфи? (вегетарианский, индийский десерт)

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

0 голосов
/ 22 марта 2009

Вот один из подходов:

Измените элемент схемы на что-то вроде:

<xs:schema xmlns="urn:my.nampespace"
    targetNamespace="urn:my.nampespace"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified">

Измените первый элемент на что-то вроде:

<xs:element name="dessert" type="recipeType"/>
<xs:element name="indian" type="recipeType"/>
<xs:complexType name="recipeType">
    <xs:sequence>
        <xs:element ref="category"/>
        <xs:element ref="headline"/>
        <xs:element ref="thumbnail"/>
        <xs:element ref="intro"/>
        <xs:element ref="media"/>
        <xs:element ref="summary"/>
        <xs:element ref="ingredients"/>
        <xs:element ref="procedures"/>
        <xs:element ref="keywords"/>
    </xs:sequence>
    <xs:attribute name="id" use="required" type="xs:NCName"/>
</xs:complexType>

Теперь вы можете определить свой XML как:

<dessert id="dessert01"
    xmlns="urn:my.nampespace" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xsi:schemaLocation="urn:my.nampespace recipe.xsd">

Или:

<indian id="indian01" 
    xmlns="urn:my.nampespace" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="urn:my.nampespace recipe.xsd">
...