newtfire / digitProjectDesign-Hub

shared repo for DIGIT 400: Digital Project Design class at Penn State Erie, The Behrend College
Creative Commons Zero v1.0 Universal
12 stars 2 forks source link

Problem with My second Relax project #12

Closed AreannaRussell closed 4 years ago

AreannaRussell commented 4 years ago

@ebeshero I'm still having problem with my Code for my second project and don't know what to do. The issue is "element "Prod" not allowed here; expected element "Album" Can anyone Help?

(this is my relax schema)

start = song song = element song {title, about, Part+} title = element title {text}

about = element about {Prod, Feat, Album, credits, Date}
    Prod = element Prod {text}
    Feat = element Feat {mixed{(name+)}}
        name = element name {mixed{(who+)}}

    Album = element Album {text}
    credits = element credits {mixed{(name+)}}
    Date = element Date {when,text}
         when = attribute when {xsd:date} 

Part = element Part {(Characters | Verse)+} Characters = element Characters {mixed{(who)+}} who = attribute who {list{("lock"| "shock"| "Santa"| "Jack"| "barrel"| "Boogie"| "PaulReub"| "CathOHar"| "DanElf")+}} Verse = element Verse{ mixed{(Alias|Characters)}} Alias = element Alias {mixed{(who|Characters)}}

_(my code I attached it to)_
<?xml version="1.0" encoding="UTF-8"?>

<?xml-model href="Russell-04.rnc" type="application/relax-ng-compact-syntax"?>
<song><title>Kidnap the Sandy Claws</title>
<about>  

<Prod>Walt Disney Records</Prod>
<Feat>Featuring <name who="PaulReub">Paul Reubens</name>,<name who="CathOHar">Catherine O’Hara</name> and, <name who="DanElf"> Danny Elfman</name></Feat>
<Prod>Produced by Walt Disney Records</Prod>
<Album>Album The Nightmare Before Christmas (Special Edition)</Album>
<credits>Written By <name who= "DanElf">Danny Elfman</name></credits>
<Date when= "1993-10-12">Release Date October 12, 1993</Date>

</about>
ebeshero commented 4 years ago

@AreannaRussell Okay, let's see if we can work through this, one step at a time.

The first thing I see that's probably causing a problem with your XML is this line:

song = element song {title, about, Characters+, Verse}

This schema rule says that the element <song> must contain exactly one <title> element, followed by exactly one <about> elements, and then one or more<Characters> elements, followed by exactly one <Verse> element. That's a problem, because it doesn't match your XML code.

In your XML code you have <Characters> elements alternating with <Verse> elements, and they appear one after the other, often alternating back and forth. Your schema rule says ALL the <Characters> elements have to appear before there is any <Verse> element. So we have to change that schema rule to match your actual code first of all. (Or we can change your XML to make it a little different--give it some structure that contains a verse together with a character...)

If you want this to match your XML, you'll want to make it possible for either <Characters> or <Verse> to show up in any order. So I'd recommend a parenthetical grouping like this:

(Characters | Verse)+

And try rewriting that line like this:

song = element song {title, about, (Characters | Verse)+ }

See how that works? Instead of using the , sequence indicator you want a grouping that says either this or that can appear, and at least one or more times.

That's a start. There will be more to fix here...

ebeshero commented 4 years ago

@AreannaRussell I have a suggestion to simplify your XML code a little when you get to verses and characters when you have multiple characters singing a verse, like here:

<Characters who="lock">LOCK</Characters>
, <Characters who="shock"> SHOCK </Characters>+ <Characters who="barrel">BARREL</Characters>]
<Verse>Now and forever </Verse>

There's a way in XML where you can give a single attribute multiple values, like this:

<Characters who="lock shock barrel">LOCK, SHOCK, + BARREL</Characters>
<Verse>Now and forever </Verse>

In XML and Relax NG there's a way you can make a rule so that spaces between values mean there's a series of values. Here is how you'd define it:

who = attribute who { list { ("lock" | "shock" | "barrel" | "Santa" | "Jack" | "Boogie" )+ } }

This is complicated the same way that mixed{} is: You have a list{} inside of which you put your options. You make a group using ( ) and you say anything in that group can appear at least one or more times. (I wrote up a longer posting about list{ } a couple of years ago here: https://github.com/ebeshero/DHClass-Hub/issues/596 if you want to read more about it.)

Try changing your XML code so it's possible use use multiple attribute values like that, and it'll be easier to read. And experiment to see if this rule lets you combine them however you need to. You could have

<Characters who="shock Santa">Shock + Santa</Characters>

for example.

I'd take this one step further. Think about in your code, how can you tell which characters go with which verse? It's not easy to tell because they sit next to each other. What if you did this instead?

<Verse>
      <Characters who="lock shock barrell">LOCK, SHOCK + BARRELL</Characters>
     <Line>Now and forever</Line>
</Verse>

Here you can make a little more structure and we add an element to separate the line being sung from the characters. You'd need to change your schema to reflect that. So your rule for <song> would look like this now:

song = element song {title, about, Verse+}

And you would need to define every Verse as containing just one Characters element, followed by probably one or more Line elements.

What do you think?

AreannaRussell commented 4 years ago

@ebeshero I'll try it and come back if there are any more problems. Thank you.

ebeshero commented 4 years ago

@AreannaRussell So, now the issue concerns the rule for the <about> element:

about = element about {Prod, Feat, Album, credits, Date}

You allow exactly one Prod, followed by exactly one Feat, followed by exactly one Album element.

What do you have in your XML code?

<song><title>Kidnap the Sandy Claws</title>
<about>  

<Prod>Walt Disney Records</Prod>
<Feat>Featuring <name who="PaulReub">Paul Reubens</name>,<name who="CathOHar">Catherine O’Hara</name> and, <name who="DanElf"> Danny Elfman</name></Feat>
<Prod>Produced by Walt Disney Records</Prod>
<Album>Album The Nightmare Before Christmas (Special Edition)</Album>

You have another <Prod> element in between <Feat> and <Album> I think you don't need it, do you? Both <Prod> elements contain the same information. Pick one and make the schema match where you want it to be.

AreannaRussell commented 4 years ago

@ebeshero It's all clear now. thank you.