 Hey everybody, this is Brian. Welcome to the 95th, wow, yeah, 95th Qt tutorial with C++ including programming. Alright, today we are going to learn how to read XML, but you notice how I put DOM at the end. It stands for document object model. There's actually two main types of reading of XML, if that makes any sense. But anyways, there's two main types. There's document object model and sacks, S-A-X. So I'll put this in the usual location. The difference between the two is DOM, document object model, which we're going to learn today. You read the entire document, then parse through and get what you want. Sacks, S-A-X on the other hand, parses the document as it reads it. There's kind of a religious holy war going on about which is the correct version. Personally, I like DOM, but you know, it's just me. Like I said, personal preference. Alright, so let's just dive right in here. First thing we're going to do is include Qt Core. I'm going to add our other includes here. Qt XML. And for good measure, let's just do Qt Debug. Now, let's put right at the top here the document object model method of reading, help if I could spell reading XML. As I said, DOM will read the entire document, then allow you to parse through it where S-A-X or S-A-X, you actually parse it as you read it. Not going to get into which one's better as personal preference. So first thing we need to do is actually load the document. So let's go Q, DOM, document. And then we will load the file. So say Q file. And of course we want our file name. And don't worry if you don't have this file. It's going to be included with the source code out on my website. And let me pull it up here real quick. This is what our document looks like. When you're reading XML specifically through DOM, you need to know the structure of the document you're going to be working with. As I said, to be well structured as it's called, an XML document needs to have one root and only one root. So book, that element is the root element. Then underneath book, we have a bunch of books. Each one has an attribute of ID and name. And each book element has some chapter elements. Each one has an ID and a name attribute. And we could have kept going and going and going. But for simplicity's sake, we're just as complex as we're going to do. Let's dive back in here. So we've got our file. And help if I actually gave it the right path here. Sorry, I was looking off on my hard drive to see what was going on. And then we'll say, if not file, open. And we want to open the QIO device, read only, and do it in text mode. So if we couldn't open it, then we just want to say, Q to bug. And we'll just say, failed to open file. And return negative one, meaning we're just going to return an error code. I'm really trying to come up with some ideas for our 100th video. That was kind of my goal here, was to get 100 cute tutorials by the end of summer. Well, I didn't meet that goal by a while. I think the end of summer was last week. But you know what? We're going to keep trudging on anyways. And then what we're going to do next, sorry, lost my train of thought here, is if document, set content. And this is where you're actually loading the content. And you're just going to give it a reference to that file. And Q will take care of the loading of the document automatically. And just return a boolean value saying, hey, actually want to say, if not loaded. It's going to say, hey, I loaded it or hey, I had a problem. And so we're just going to say, failed to load document. And that's how we actually populate our XML document, our Q DOM document, is just set content reference to file. And then of course, you know, we want to do a file closing here. That way that is closed. And right here, get the root element. So what we want to do next is just say, Q DOM element. And let's just for argument sake, call it root equal document dot first child element. What that'll do is that we'll get the root element of this document. Now let's just give this a good compile and run, just to see what happens here. I want to make sure we can actually do this. It didn't print any failure notices out. So we know we did good. It actually loaded that up and found the root element. So let's actually just throw a Q debug finished in here. That way we know it finishes without any problem. But yeah, if you guys got any ideas, feedback about what the 100th Q tutorial should be, let me know. Try to keep it somewhat simplistic. I don't want to, you know, write a full 3D first person shooter Lake Quake, although that would be fun. It would take a horrendously long amount of time. And I don't think I could actually upload that file to YouTube anyway. So all right, now we have our root element. List the books. This is where we're going to break off. We're going to make a function. And the reason why is let's look at this file. I'm a big, big fan of design patterns. And what a design pattern would be is you see book and chapter have a very similar structure. The only thing really different is the tag element book and chapter. They both have an attribute of ID. They both have an active name. So you could say write a function that pulls that data out and it could be a book or a chapter. You'll see what I need here in a minute. Let's scroll up here. So we're just going to make our void and let's just call it list elements. And we want to give it some parameters here. Let's say qdom document element. Whoops. We want to get the element at this that it's at. And we're just going to call this root because that's the root element of whatever we're passing over. Not to be confused with this element root. Let me jump over to the file here. See for this element right here, its root would actually be book ID 3. Book ID 3's root element would actually be this books tag. I know some of you XML geeks out there are going to argue, well, actually the root element is always going to be books. This is a cute tutorial, not an XML tutorial. Let it go. Take a deep breath. All right now, qstring. And we want tag name and qstring, let's say attribute. We want to be able to pull out the tag name and the attribute. All right now, let's qdom node list. And what this is, is it gets a list of nodes from an element. And we're going to call this items equal root dot elements by tag name. And what this will do is it will extract all the elements with a similar tag name. Hence the variable tag name. So what you do is you pass this function, you say, okay, I want a list of all the elements that start with book. So it'll give you a list of all the elements that start with book or chapter, et cetera, et cetera. And I'll do that based off the current element you pass it to, aka our root element. All right now, we just want to throw a qdebug out here. And we'll say total items equal. And we want to say items dot count. That way, we just have an idea of the total items here. And then let's just go for and I equals zero. And we'll say I less than items count. And then we want to, of course, do a increment here. Well, I love doing these videos. I'm developing a very nasty habit of talking to myself. I think I had an entire conversation with myself out in the kitchen. And I don't think I won that argument. So I think my daughter's been starting to look at me a little funny. And what we're going to do next is we're going to just extract that node. So say at. So we're going to get that that node item at that index. Now, what's the difference between a node and an element? Anybody show of hands? Well, and this is my rough understanding, somebody please correct me if I'm wrong, but a node could be anything in the document. An element is an actual element item, whereas a node could be any little part of this. So what we would need to do now is actually convert that to an element. Now, why did they do that? Well, because it's easier to just parse everything and generically call it a node, and then examine it later to see if it's actually an element. Item node is element. So we're saying if it is an element, then do some magic. So we'll get our element here. And we'll just call this item Ali. Don't ask me where I get these names. A couple of you wrote in going Brian, why don't you use camel case cute uses it and I think you should too. Well, that's an excellent point. And you know, I'm very sorry I haven't been doing it. Unfortunately, I've gotten spoiled with other languages and I get kind of in a hurry. So there's really no excuse for it other than just sheer laziness on my part, I have to admit that. And I will try to do a better job in the future. Now we want to get our attribute here. And the attribute is of course going to be the attribute variable that we're passing to it, the ID or name. So quick review. We're going to actually just copy this real quick. We open our file. Once the files open, we set the documents contents with the files contents. If we can't we say a tough luck. And then we return close the file. Find the root element, which is the first child element. Then we want to call our function here, which lists the books. In this case, we are actually calling root. And we want to look for book. And we want the let's say the name attribute. That way it's a little more obvious what's going on here. So we will call this jump back up here. And first thing it does is it grabs a queue DOM node list, which is just a list of elements here are actually sorry, a list of nodes based on the tag name. Remember this is going to be book gives us the total items and then for each one it just goes through and says okay, is it an element if so convert it and then print out the attribute which will be name. See, we're getting name here. So let's save and run fingers crossed. Everything goes good. We get this total items 10. My book zero one two three four five six seven eight nine finished. Pretty neat stuff. Huh? So we've gotten those. Now how do we get the chapters out of here? Hmm. Well, if you think about it, chapters just just a child element of each book. So it won't be too hard for us to actually extract that out. So let's actually give me one second. I got to pause it. Sorry about that. My newer cat. If any of you guys remember from previous videos, one of my cats died and I got a new cat. Well, the new cat is fascinated with light bulbs. Don't ask me why I don't understand it myself. So I'm sitting in my little office typing away making this beautiful tutorial for you. And he walks up and just starts swatting the light bulb in the lamp. Now one of these days I'm going to come home to a fried cat. I know that I've just come to terms with that. But until then I'm trying to keep little guy away from the light bulbs. Anybody else have cats that do weird things like that? Let me know because he's just really got me freaked out here. Alright, so now we're going to get the chapters. And if anybody thought this was going to be a for loop, you are absolutely right. We skipped a step here, didn't we? Yes, we did. Let me back up here and comment this out. Got a little ahead of myself. Sorry, I'm watching my cat out of the corner of my eye. Little orange demon. So what we're going to do is get a queue DOM node list that should look familiar because we just used it. We're going to call it books. And we're going to say root elements by tag name. So what we're going to do is say get a list of books. And then we're going to jump into our for loop here. And then for each node item in each book, we're going to rip through this. And we're going to say queue DOM node. And if you're asking yourself, hmm, there's probably a better way of doing this. Yes, you're right. There is probably a better way of doing this. I'm doing it this way simply for illustration to show you basically bare bones without getting too complex and how this works. Just exactly how it works. So so we're going to get the book at position I should say at index I. Once again, convert to an element if book node is element. And this should look really familiar from the function we wrote earlier. So if it's an element, then we get the element. And we'll just call it book kitty. I'm watching you quit swatting that light bulb. And then we want to just say, uh, list elements, book, because that's our that's going to be our route chapter. Because that's what we want to look for. And name. Save this, run it. Now our output is total items. We've got our chapters here. And if you notice, if you scroll up, here's our first attempt. You've got your books. And then we're getting the chapters out of each book. Let's polish this up a little bit. All right, so let's throw in a debug statement here. And this might make it a little clearer what's going on here. Pull out the attribute from the book element. Let's rerun this. Now you see it's a little clear. We did our initial where we get all our books. Now we're doing a more advanced method where we're saying chapters in my book zero because my book zero is the first one. And then we're getting the individual chapters, and chapters in my book one, two, three, four, five, I mean, all the way up. So that's how you recursively parse through these. Now, there are some flaws in this application. I'll leave that up to you to kind of pick and find them. One thing I would really recommend if you're going to do a lot of XML programming is get really used to just, you know, streamlining your code. Don't do a bunch of nestled for loops and if thens really use functions, I mean, really use the power of the language you're working with. Don't just do a bunch of, you know, recursive, if then for else's and I mean, your code will just look horrendous. So that is how in a nutshell, you parse an XML document. This is Brian. Thank you for watching. Hope you found this educational and entertaining kitten. I'm watching you quit touching that light bulb. Sorry guys. Maybe next time I'll just lock the door and lock my demonic little cats out of here, even though they love me. If you have any ideas for the hundredth video, I'm really looking forward to your feedback and I apologize. Once again, I'm still way behind on feedback. Unfortunately, it's it's very difficult to come home from work and then plow through 100 plus emails. But I'm trying. Try to keep your ideas for the hundredth video simple, but unique. Try not to redo anything we've already done. Some of the ideas that I've had so far were an IRC client. Basic 3D graphics programming, which that seems very tricky. Things I have had absolutely zero experience in that. What was another one? Yeah, how to make zip files, which we would have to backbone off a third party library. I actually kind of like that idea because it forces us to step outside our comfort zone. But anyways, I'm babbling. Shoot me your ideas and I'll see you next time.