Storing XML into Postgres - sql

I have an XML document that needs to get stored in an SQL db (Postgres).
I've already seen how that's done, but I have a question: do I just create a single table with a xml field and place the whole document there? This is a document about movies and so (movies, actors...) that has information to be later retrieved.
I've never worked with XML in databases, so I'm a little confused.
Here's an example of my XML:
<?xml version="1.0" encoding="UTF-8"?>
<cinema xmlns="movies"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="movies file:/C:/Users/Fabio/git/LAPD/movies.xsd">
<persons>
<person id="P1">
<name>Samuel L. Jackson</name>
<birth>1948-12-21</birth>
</person>
<person id="P2">
<name>Leonardo Di Caprio</name>
<birth>1974-11-11</birth>
</person>
<person id="P3">
<name>Quentin Tarantino</name>
<birth>1963-03-27</birth>
</person>
</persons>
<movies>
<movie id="M1">
<title>Pulp Fiction</title>
<length>154</length>
<year>1994</year>
<description>The lives of two mob hit men,
a boxer, a gangster's wife, and a pair
of diner bandits intertwine in four tales of violence and redemption</description>
<crew>
<director ref="P3"/>
<writer ref="P3"/>
</crew>
<cast>
<actor ref="P1"/>
</cast>
<rate>
<imdb>8.9</imdb>
<rottentomatoes>9</rottentomatoes>
<moviedb>7.8</moviedb>
<average>8.57</average>
</rate>
<numOscars>1</numOscars>
</movie>
<movie id="M2">
<title>Django Unchained</title>
<length>165</length>
<year>2012</year>
<description>With the help of a German bounty hunter,
a freed slave sets out to rescue his wife
from a brutal Mississippi plantation owner.</description>
<crew>
<director ref="P3"/>
<writer ref="P3"/>
</crew>
<cast>
<actor ref="P1"/>
<actor ref="P2"/>
</cast>
<rate>
<imdb>8.5</imdb>
<rottentomatoes>8</rottentomatoes>
<moviedb>7.4</moviedb>
<average>7.97</average>
</rate>
<numOscars>2</numOscars>
</movie>
</movies>

You can store a whole XML document as value in a single xml column or you can extract data and store it in a more or less normalized form.
Which is better, depends on all the details of your application that are unknown to us.
Here is a related answer discussing pros and cons of storing document types vs. db normalization:
Does JSONB make PostgreSQL arrays useless?

Save XML as a text column of DB so that you can also apply equality operator easily. You may find some error on insertion for " or ' so try to replace them with other characters like ~ or `, both.

Related

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

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.

SQL update Statement converting to XQuery

So as the above states I am rather stuck when it comes to converting an update sql query to xquery my example for the update is as shown below.
UPDATE Products
SET [List Price] = 19
WHERE [ID]= 1;
Where needed just assume a variable, I get how XQuery works and the pathing just use random examples if it's the only way. I just can't find a good example that explains how to update the same way.
<Products>
<Supplier_x0020_IDs>
<Value>4</Value>
</Supplier_x0020_IDs>
<ID>1</ID>
<Product_x0020_Code>NWTB-1</Product_x0020_Code>
<Product_x0020_Name>Northwind Traders Chai</Product_x0020_Name>
<Standard_x0020_Cost>13.5</Standard_x0020_Cost>
<List_x0020_Price>18</List_x0020_Price>
<Reorder_x0020_Level>10</Reorder_x0020_Level>
<Target_x0020_Level>40</Target_x0020_Level>
<Quantity_x0020_Per_x0020_Unit>10 boxes x 20 bags</Quantity_x0020_Per_x0020_Unit>
<Discontinued>0</Discontinued>
<Minimum_x0020_Reorder_x0020_Quantity>10</Minimum_x0020_Reorder_x0020_Quantity>
<Category>Beverages</Category>
</Products>
This is how the XML looks like, it's stupidly messy hence why I avoided posting it but now it's stuck again
If you want to do update in XQuery, then you need to use XQuery Update and it really depends whether your implementation supports this or not.
As you have not told us what your XML looks like, I will assume something like:
<Products>
<Product>
<ID>1</ID>
<ListPrice>20</ListPrice>
</Product>
<Product>
<ID>2</ID>
<ListPrice>7</ListPrice>
</Product>
</Products>
If so you can use the following XQuery Update expression:
replace value of node /Products/Product[ID eq "1"]/ListPrice with "19"
Note, that I have assumed that your XQuery processors is schema unaware and does not know the types of your nodes, so I have assumed strings throughout. Also I have removed the space from "List Price" as XML elements cannot contain spaces in their names.

performing calculations with values in xml CLOB which has identical tags using sql

I've got a table (event_archive) and one of the columns(event_xml) has CLOB data in xml format as below. Is there a way to use SQL to summate the values of the "xx" tag? Please help as i'm completely baffled. Even simply extracting the values is a problem as there are 2 "xx" tags within the same root. Thanks in advance.
<?xml version="1.0" encoding="UTF-8"?>
<event type="CALCULATION">
<source_id>INTERNAL</source_id>
<source_participant/>
<source_role/>
<source_start_pos>1</source_start_pos>
<destination_participant/>
<destination_role/>
<event_id>123456</event_id>
<payload>
<cash_point reference="abc12345">
<adv_start>20120907</adv_start>
<adv_end>20120909</adv_end>
<conf>1234</conf>
<profile>3</profile>
<group>A</group>
<patterns>
<pattern id="00112">
<xx>143554.1</xx>
<yyy>96281.6</yyy>
<adv>875</adv>
</pattern>
<pattern id="00120">
<xx>227606.1</xx>
<yyy>97539.8</yyy>
<adv>18181</adv>
</pattern>
</patterns>
</cash_point>
</payload>
</event>
Different databases handle XML differently. There's no standard way of dealing with XML payloads via raw, standard SQL. So you'll need to look at your actual DB implementation to find out what support they have.

VB MS Word: Bind XML into an ordered lists?

Is there any way to bind ordered lists to XML documents in MS Word?
Currently I have xml such as:
<?xml version="1.0"?>
<myvars>
<name>foo</name>
</myvars>
Then I load and map it to a contentcontrol:
ActiveDocument.CustomXMLParts.Add
ActiveDocument.CustomXMLParts(5).Load ("c:\test.xml")
Dim strXPath1 As String
strXPath1 = "/myvars/name"
ActiveDocument.ContentControls(1).XMLMapping.SetMapping strXPath1
However this is only useful for single texts. Is there anyway to map xml enteries to ordered lists? For example:
<?xml version="1.0"?>
<myvars>
<person>
<name>foo</name>
<alias>bar</alias>
<alias>chew</alias>
</person>
<person>
<name>alpha</name>
<alias>bravo</alias>
<alias>charlie</alias>
</person>
</myvars>
mapped into the word document so that it shows up as ordered lists:
1. foo
a. bar
b. chew
2. alpha
a. bravo
b. charlie
Basically, the answer is you cannot. You can only map simple text and combo box type content controls to XML.

Import Xml nodes as Xml column with SSIS

I'm trying to use the Xml Source to shred an XML source file however I do not want the entire document shredded into tables. Rather I want to import the xml Nodes into rows of Xml.
a simplified example would be to import the document below into a table called "people" with a column called "person" of type "xml". When looking at the XmlSource --- it seem that it suited to shredding the source xml, into multiple records --- not quite what I'm looking for.
Any suggestions?
<people>
<person>
<name>
<first>Fred</first>
<last>Flintstone</last>
</name>
<address>
<line1>123 Bedrock Way</line>
<city>Drumheller</city>
</address>
</person>
<person>
<!-- more of the same -->
</person>
</people>
I didn't think that SSIS 2005 supported the XML datatype at all. I suppose it "supports" it as DT_NTEXT.
In any case, you can't use the XML Source for this purpose. You would have to write your own. That's not actually as hard as it sounds. Base it on the examples in Books Online. The processing would consist of moving to the first child node, then calling XmlReader.ReadSubTree to return a new XmlReader over just the next <person/> element. Then use your favorite XML API to read the entire <person/>, convert the resulting XML to a string, and pass it along down the pipeline. Repeat for all <person/> nodes.
Could you perhaps change your xml output so that the content of person is seen as a string? Use escape chars for the <>.
You could use a script task to parse it as well, I'd imagine.