Optaplanner: Howto change the sample XML in the nurserostering demo? - optaplanner

I am stucked with the Nurserostering example in Optaplanner. I would like to change the input XML to play around (for example increase the number of nurses from 30 to 100), and I find it's very complicated to manually edit it, so I think there must be some kind of 'generator', or maybe I should make my own 'XML generator'.
For example I see every node in the sample has a unique id, so if I want to increase the number of nurses, it's not as simple as copying the last Employee node and pasting it 70 times; I should check every id inside and increase it accordingly.
<Employee id="358">
<id>6</id>
<code>6</code>
<name>6</name>
<contract reference="36"/>
<dayOffRequestMap id="359">
<entry>
<ShiftDate reference="183"/>
<DayOffRequest id="360">
<id>18</id>
<employee reference="358"/>
<shiftDate reference="183"/>
<weight>1</weight>
</DayOffRequest>
...
Therefore, I ask, is there any method to generate this (or other) XML?

The best way I could think of is write a small java application where you could load the original dataset, and then add any number of employees you want (using java code of course). At least this is what I do when I need a bigger dataset or when I toy around the model data (because the dataset need to be updated too).
Oh I almost forgot, sometimes I use xml viewer to help me do some manual copy and paste work (it help me a lot since the row is thousand lines).

You looked at the wrong XML file! Instead of taking e.g. data/nurserostering/unsolved/medium01.xml, take data/nurserostering/import/medium01.xml.
<Employees>
<Employee ID="0">
<ContractID>0</ContractID>
<Name>0</Name>
<Skills>
<Skill>Nurse</Skill>
</Skills><
</Employee>
[...]
<DayOffRequests>
<DayOff weight="1">
<EmployeeID>0</EmployeeID>
<Date>2010-01-21</Date>
</DayOff>
[...]
This file can then easily be edited and imported in OptaPlanner.

Related

Check if XML nodes are empty in SQL

Hi I am new to XML manipulation, my question would be if there is a possibility of detecting if the XML node is an empty node like this: <gen:nodeName />
I am able to manipulate single nodes however I would be interested if there is an approach like a loop or recursive function that could save some time doing manual labor looking trough every single node. I have no idea how to approach this problem though.
Thanks for help.
You did not specify the dialect of SQL ([sql] is not enough, please specify always the RDBMS incl. version).
This is for SQL-Server, but the semantics should be the same.
DECLARE #xml XML=
N'<root>
<SelfClosing />
<NoContent></NoContent>
<BlankContent> </BlankContent>
<HasContent>blah</HasContent>
<HasContent>other</HasContent>
</root>';
SELECT #xml.query(N'/root/*') AS AnyBelowRoor --All elements
,#xml.query(N'/root/*[text()]') AS AnyWithTextNode --blah and other
,#xml.query(N'/root/*[not(text())]') AS NoText --no text
,#xml.query(N'/root/*[text()="blah"]') AS AnyWithTextNode--blah only
The <SelfClosing /> is semantically the same as the <NoContent><NoContent>. There is no difference.
It might be a surprise, but a blank as content is taken as empty too.
So the check for empty or not empty is the check for the existance of a text() node. one can negate this with not() to find all without a text().
Interesting: The result for NoText comes back as this (SQL-Server)
<SelfClosing />
<NoContent />
<BlankContent />
The three elements are implicitly returned in the shortest format.

SQL Date column in xml

StudentID ExamID 09/05/2017 08/05/2017 07/05/2017 06/05/2017 05/05/2017
123 AS12 12
123 AS13 13 23
While convert the above using "FOR XML PATH , Elements" in sql statement. I got the error.
error:Column name '09/05/2017' contains an invalid XML identifier as
required by FOR XML; '2'(0x0032) is the first character at fault.
Is there any way I will get XML in format:
<row>
<StudentID>123</StockID>
<LessonID>AS13</LessonID>
<09/05/2017>13</09/05/2017>
<08/05/2017>23</08/05/2017>
<07/05/2017></07/05/2017>
<06/05/2017></06/05/2017>
<05/05/2017></05/05/2017>
</row>
It is a very bad design, to store your date-based values in columns of the student table. Whenever you have to add a column in order to add more data, the design is bad... This should be stored in a related side table, while a PIVOT query constructs this output format, whenever you need it.
And: Avoid culture specific date formats!!!
How should one know, wheter 06/05/2017 is the 6th of May or the 5th of June? Use ISO8601 like 2017-05-06 (which makes it sure, that you think about the 6th of May)
About your question: No, this is impossible!
XML does not allow an element's name like '05/05/2017'. You must start with a non-numeric character or an underscore and several characters like the / are forbidden...
Try to create your XML similar to
<row>
<StudentID>123</StockID>
<LessonID>AS13</LessonID>
<Marks>
<Mark date="2017-05-09">13<Mark>
<Mark date="2017-05-08">23<Mark>
[... more of them ...]
</Marks>
</row>
This error goes back to how to treat strings in the language you wish to program in. In this case once you are inside the brackets(<>) the slash is (/) is a special character and the first set of algorithms that process this (regex) XML identify the slash as an issue thereby throwing the error.
Additionally you may want to consider how you want to treat your objects in XML. First group is the class, the class has many students, and the students take many lessons, and each lesson has a grade. (or in this case it looks like a lesson has many grades, not shown here)
<CLASS>
<STUDENT>
<StudentID>123</StudentID>
<LESSON>
<LessonID>AS12</LessonID>
<DATE>09/05/2017</DATE>
<GRADE>93.00</GRADE>
</LESSON>
<LESSON>
<LessonID>AS12</LessonID>
<DATE>08/05/2017</DATE>
<GRADE>93.00</GRADE>
</LESSON>
</STUDENT>
<STUDENT>
...
</STUDENT>
</CLASS>

How would I read this "XML" type?

This is the response (XML) :
<?xml version="1.0" encoding="UTF-8"?>
<root response="True">
<movie
title="Taken 3"
year="2015"
rated="PG-13"
released="09 Jan 2015"
runtime="109 min"
genre="Action, Crime, Thriller"
director="Olivier Megaton"
writer="Luc Besson, Robert Mark Kamen"
actors="Liam Neeson, Maggie Grace, Famke Janssen, Forest Whitaker"
plot="Liam Neeson returns as ex-covert operative Bryan Mills, whose long awaited reconciliation with his ex-wife is tragically cut short when she is brutally murdered. Consumed with rage, and framed for the crime, he goes on the run to evade the relentless pursuit of the CIA, FBI and the police. For one last time, Mills must use his 'particular set of skills,' to track down the real killers, exact his unique brand of justice, and protect the only thing that matters to him now - his daughter."
language="English"
country="France"
awards="N/A"
poster="http://ia.media-imdb.com/images/M/MV5BNjM5MDU3NTY0M15BMl5BanBnXkFtZTgwOTk2ODU2MzE#._V1_SX300.jpg"
metascore="N/A"
imdbRating="8.2"
imdbVotes="1,159"
imdbID="tt2446042"
type="movie"
/>
</root>
How would I get data out of this type of XML? Like say I wanted to get "title" and imdbRating out of this data, which way should I go?
this is the code I have but it doesn't really work ...
Dim xml = XDocument.Load("config.xml")
MsgBox(xml.<root>.<movie>.<title>.value)
You can use LINQ to XML to read the XDocument type.
First, add these imports to the top of your file:
Imports System.Xml
Imports System.Xml.Linq
Then you can use methods Element and Attribute to get to the element that you need:
Dim xml = XDocument.Load("config.xml")
MsgBox(xml.Element("root").Element("movie").Attribute("title").Value)
You can find additional information about LINQ to XML in MSDN

How to parse simple xml file

>> ? xml
No information on xml
There's parse-xml but it seems to me that it was for Rebol2.
I've searched for xml scripts in rebol.org and found xml-object.r that seemed to me like the most up to date from all searches.
I know about altxml, too, but the examples given are for html.
So, I'd like to ask about my choices if I want to parse and use information of +1GB of files of this simplified structure:
<?xml version="1.0" encoding="Windows-1252" standalone="yes"?>
<SalesFile xmlns="urn:StandardSalesFile-1.0">
<Header>
<SalesFileVersion>1.01</SalesFileVersion>
<DateCreation>2014-04-30</DateCreation>
</Header>
<SalesInvoices>
<Invoice>
<InvoiceNo>INV 1/1</InvoiceNo>
<DocumentStatus>
<InvoiceStatus>N</InvoiceStatus>
<InvoiceStatusDate>2014-01-03T17:57:59</InvoiceStatusDate>
</DocumentStatus>
</Invoice>
<Invoice>
<InvoiceNo>INV 2/1</InvoiceNo>
<DocumentStatus>
<InvoiceStatus>N</InvoiceStatus>
<InvoiceStatusDate>2014-01-03T17:59:12</InvoiceStatusDate>
</DocumentStatus>
</Invoice>
</SalesInvoices>
</SalesFile>
Is Rebol3 going to have a parse-xml tool? Should I use xml-object? If so how? Because it's still beyong my novice level of the language. Other option?
There is also a Rebol 3 library by Christopher Ross-Gill called alt-xml.
http://www.ross-gill.com/page/XML_and_REBOL
This can translate the XML to either a block! or object! representation.
Your question states that these XML files are large and may not fit in main memory. I would suggest that creating 1GB XML files is not best practice as many parsers, including this one, do attempt to load the files into memory.
To support this you will have to chunk the files yourself by using open on the file and copy/part chunks out of the file. This is a bit messy, but it will work.
One way to make this cleaner is to use parse as per HostileFork's suggestion and modify the series as you parse it. Parse is very flexible in this regard.
Ideally parse would be able to work directly on port! objects, but this is only a future wish list item at the moment.
Do you really need to deal with the XML file as structure? If not, have you considered just using PARSE?
(Warning: the following is untested, I'm just presenting the concept.)
Invoices: copy []
parse my-doc [
<?xml version="1.0" encoding="Windows-1252" standalone="yes"?>
thru <SalesFile xmlns="urn:StandardSalesFile-1.0">
thru <Header>
thru <SalesFileVersion> copy SalesFileVersion to </SalesFileVersion>
</SalesFileVersion>
thru <DateCreation> copy DateCreation to </DateCreation>
</DateCreation>
thru </Header>
thru <SalesInvoices>
any [
thru <Invoice>
(Invoice: object [])
thru <InvoiceNo> copy InvoiceNo to </InvoiceNo>
</InvoiceNo>
(Invoice/No: InvoiceNo)
thru <DocumentStatus>
thru <InvoiceStatus> copy InvoiceStatus to </InvoiceStatus>
</InvoiceStatus>
(Invoice/Status: InvoiceStatus)
thru <InvoiceStatusDate> copy InvoiceStatusDate to </InvoiceStatusDate>
</InvoiceStatusDate>
(Invoice/StatusDate: InvoiceStatusDate)
thru </DocumentStatus>
thru </Invoice>
]
thru </SalesInvoices>
thru </SalesFile>
to end
]
If you know you have well-formed XML and don't want a dependency on a library for processing clunky-ol' XML, Rebol can get pretty far and clear with PARSE. As TAG! is just a subclass of string, you can make things look relatively literate. And it's much more lightweight to just work with the strings.
Though if structural manipulations are required, you'll need something that makes a DOM. Altxml is the go-to right now, AFAIK.
(Hmm...I had a name for the pattern copy x to <foo> <foo> that escapes me at the moment, but this is a good case for it.)
%Rebol-Dom.r or %rebol-dom-mdlparser.r,
If your willing to use rebol2 with parse to seek thru to the node-name, then copy a chunk of data, you could feed that to Rebol-Dom.r getnodename "salesInvoice" and append that node-element to a block repetitively.

list=alllinks confusion

I'm doing a research project for the summer and I've got to use get some data from Wikipedia, store it and then do some analysis on it. I'm using the Wikipedia API to gather the data and I've got that down pretty well.
What my questions is in regards to the links-alllinks option in the API doc here
After reading the description, both there and in the API itself (it's down and bit and I can't link directly to the section), I think I understand what it's supposed to return. However when I ran a query it gave me back something I didn't expect.
Here's the query I ran:
http://en.wikipedia.org/w/api.php?action=query&prop=revisions&titles=google&rvprop=ids|timestamp|user|comment|content&rvlimit=1&list=alllinks&alunique&allimit=40&format=xml
Which in essence says: Get the last revision of the Google page, include the id, timestamp, user, comment and content of each revision, and return it in XML format.
The allinks (I thought) should give me back a list of wikipedia pages which point to the google page (In this case the first 40 unique ones).
I'm not sure what the policy is on swears, but this is the result I got back exactly:
<?xml version="1.0"?>
<api>
<query><normalized>
<n from="google" to="Google" />
</normalized>
<pages>
<page pageid="1092923" ns="0" title="Google">
<revisions>
<rev revid="366826294" parentid="366673948" user="Citation bot" timestamp="2010-06-08T17:18:31Z" comment="Citations: [161]Tweaked: url. [[User:Mono|Mono]]" xml:space="preserve">
<!-- The page content, I've replaced this cos its not of interest -->
</rev>
</revisions>
</page>
</pages>
<alllinks>
<!-- offensive content removed -->
</alllinks>
</query>
<query-continue>
<revisions rvstartid="366673948" />
<alllinks alfrom="!2009" />
</query-continue>
</api>
The <alllinks> part, its just a load of random gobbledy-gook and offensive comments. No nearly what I thought I'd get. I've done a fair bit of searching but I can't seem to find a direct answer to my question.
What should the list=alllinks option return?
Why am I getting this crap in there?
You don't want a list; a list is something that iterates over all pages. In your case you simply "enumerate all links that point to a given namespace".
You want a property associated with the Google page, so you need prop=links instead of the alllinks crap.
So your query becomes:
http://en.wikipedia.org/w/api.php?action=query&prop=revisions|links&titles=google&rvprop=ids|timestamp|user|comment|content&rvlimit=1&format=xml