Simple way to reformat a large(ish) XML file? - mysql

I'm trying to build a store locator that uses data from an XML file to load the locations.
The current file is set out such as below, once exported from phpmyadmin:
<table name="tblLabs">
<column name="LabID">76</column>
<column name="RegionID">8</column>
<column name="Consultant">Dr M E Herd</column>
<column name="BMS">Mrs C Pickup</column>
<column name="AP">NULL</column>
<column name="AdditionalStaff">NULL</column>
<column name="Department">Pathology Dept</column>
<column name="OrganizationName">Bury General Hospital</column>
<column name="Address">Walmersley Road</column>
<column name="Address1">Bury</column>
<column name="City">Lancs</column>
<column name="PostCode">BL9 6PG</column>
<column name="Tel">0161 1234 1234</column>
<column name="Fax">0161 1234 1234</column>
<column name="EMail">email#email.com</column>
<column name="Comments"></column>
<column name="Public">1</column>
<column name="lat">0.000000</column>
<column name="lng">0.000000</column>
<column name="type"></column>
</table>
For it to work with the javascript file I need it to be formated as below:
<markers>
<marker Consultant="Dr M E Herd"
BMS="Mrs C Pickup"
AP="NULL"
AdditionalStaff="NULL"
Department="Pathology Dept"
name="Bury General Hospital"
address="Walmersley Road"
city="Bury"
state="Lancs"
postal="BL9 6PG"
phone="0161 705 3274"
Fax="0161 705 3418"
email="email#email.com"
Comments=""
lat="53.6145706"
lng="-2.2927511"
type="" />
</markers>
Is there a way I can export from phpmyadmin in the format as above? Or is there another way I can quickly reformat the data as to the way I need it? I also need to add in lat & lng from a batch geocode service I am using.

This can be done rather easily with this XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="table">
<markers>
<marker>
<xsl:for-each select="column">
<xsl:attribute name="{#name}">
<xsl:value-of select="text()" />
</xsl:attribute>
</xsl:for-each>
</marker>
</markers>
</xsl:template>
</xsl:stylesheet>
You can test it online.
This does not add the latitude and longitude, though - but why aren't you storing this in MySQL?

Related

sub-group using XSLT

I have a source xml like below. Im trying to convert to a desired format using xslt as shown below
**Sample XML**
<table>
<row>
<tablename>table1</tablename>
<columnname>col1</columnname>
<columnDesc>col1_desc</columnDesc>
<columnDataType>Number</columnDataType>
<ultimateSourceTable>sourceTable1</ultimateSourceTable>
</row>
<row>
<tablename>table1</tablename>
<columnname>col1</columnname>
<columnDesc>col1_desc</columnDesc>
<columnDataType>Number</columnDataType>
<ultimateSourceTable>sourceTable2</ultimateSourceTable>
</row>
<row>
<tablename>table2</tablename>
<columnname>table2_col1</columnname>
<columnDesc>table2_col1_desc</columnDesc>
<columnDataType>String</columnDataType>
<ultimateSourceTable>sourceTable2</ultimateSourceTable>
</row>
</table>
current output
<Prod>
<dataBase>
<physicalTableName>
<tableName>table1</tableName>
</physicalTableName>
<columnList>
<name>col1</name>
<name>col1</name>
<name>table2_col1</name>
</columnList>
<finalSourceList>
<column>
<columnName>col1</columnName>
<ultimateSourceTable>sourceTable1</ultimateSourceTable>
</column>
<column>
<columnName>col1</columnName>
<ultimateSourceTable>sourceTable2</ultimateSourceTable>
</column>
</finalSourceList>
<physicalTableName>
<tableName>table2</tableName>
</physicalTableName>
<columnList>
<name>col1</name>
<name>col1</name>
<name>table2_col1</name>
</columnList>
<finalSourceList>
<column>
<columnName>table2_col1</columnName>
<ultimateSourceTable>sourceTable2</ultimateSourceTable>
</column>
</finalSourceList>
</dataBase>
Desired output:
<Prod>
<dataBase>
<physicalTableName>
<tableName>table1</tableName>
</physicalTableName>
<columnList>
<name>col1</name>
<columnDesc>col1_desc</columnDesc>
<columnDataType>Number</columnDataType>
</columnList>
<finalSourceList>
<column>
<columnName>col1</columnName>
<ultimateSourceTable>sourceTable1</ultimateSourceTable>
</column>
<column>
<columnName>col1</columnName>
<ultimateSourceTable>sourceTable2</ultimateSourceTable>
</column>
</finalSourceList>
<physicalTableName>
<tableName>table2</tableName>
</physicalTableName>
<columnList>
<name>table2_col1</name>
<columnDesc>table2_col1_desc</columnDesc>
<columnDataType>String</columnDataType>
</columnList>
<finalSourceList>
<column>
<columnName>table2_col1</columnName>
<ultimateSourceTable>sourceTable2</ultimateSourceTable>
</column>
</finalSourceList>
</dataBase>
</Prod>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" />
<xsl:template match="/">
<Prod>
<xsl:apply-templates />
</Prod>
</xsl:template>
<xsl:key name="kElsByGroup" match="row" use="tablename" />
<xsl:key name="TableColByGroup" match="row" use="concat(tablename,'|',columnname)" />
<xsl:template match="row">
<xsl:apply-templates />
</xsl:template>
<xsl:template
match="row[generate-id()=generate-id(key('kElsByGroup',tablename)[1])]">
<dataBase>
<physicalTableName>
<tableName>
<xsl:value-of select="tablename"></xsl:value-of>
</tableName>
</physicalTableName>
<columnList>
<xsl:for-each
select="//row[generate-id()=generate-id(key('TableColByGroup',concat(tablename,'|',columnname))[1])]">
<xsl:element name="column">
<name>
<xsl:value-of
select="columnname"></xsl:value-of>
</name>
</xsl:element>
</xsl:for-each>
</columnList>
<finalSourceList>
<xsl:for-each
select="key('kElsByGroup',tablename)">
<xsl:element name="column">
<columnName>
<xsl:value-of
select="columnname"></xsl:value-of>
</columnName>
<sourceTable>
<xsl:value-of
select="ultimateSourceTable"></xsl:value-of>
</sourceTable>
</xsl:element>
</xsl:for-each>
</finalSourceList>
</dataBase>
</xsl:template>
<xsl:template
match="row[not(generate-id()=generate-id(key('kElsByGroup',tablename)[1]))]" />
</xsl:stylesheet>
So, I basically want to have only unique value in my columnList tag. I'm trying to subgroup using muenchian grouping but, I still 2 entries of col1 in my columnList tag. Can someone help me out?
With a single table element in the source containing rows of different tables it seems you can solve it using modes to process rows twice, once to create the data of a result table and the second time to create the details of each result table:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="table" match="row" use="tablename"/>
<xsl:key name="col" match="row" use="concat(tablename, '|', columnname)"/>
<xsl:template match="table">
<Prod>
<dataBase>
<xsl:apply-templates select="row[generate-id() = generate-id(key('table', tablename)[1])]" mode="table"/>
</dataBase>
</Prod>
</xsl:template>
<xsl:template match="row" mode="table">
<physicalTableName>
<xsl:value-of select="tablename"/>
</physicalTableName>
<columnList>
<xsl:apply-templates select="key('table', tablename)[generate-id() = generate-id(key('col', concat(tablename, '|', columnname))[1])]/columnname"/>
</columnList>
<finalSourceList>
<xsl:apply-templates select="key('table', tablename)"/>
</finalSourceList>
</xsl:template>
<xsl:template match="row/columnname">
<name>
<xsl:value-of select="."/>
</name>
</xsl:template>
<xsl:template match="row">
<column>
<xsl:apply-templates select="*[not(self::tablename)]" mode="source-list"/>
</column>
</xsl:template>
<xsl:template match="row/columnname" mode="source-list">
<columnName>
<xsl:value-of select="."/>
</columnName>
</xsl:template>
<xsl:template match="row/ultimateSourceTable" mode="source-list">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/naZYrpu/1

Liquibase CSV loadData fails with quoted string containing a comma

I am trying to load CSV file into SQLserver table using Liquibase change log set.
When saved XLSX file as CSV file, column containing comma saved in double quotes (please see 3rd value below), this is fine as per standards but liquibase is ignoring double quotes and considering comma inside the double-quotes.
13,OV,"Diabetes outpatient self-management training services individual,per 30 minutes",77.82,1,0,1/4/2016,,G0108
Error messgae from command line terminal:
CSV file v2.1/r21/TestData20212021.csv Line 21 has 10 values defined, Header has 9. Numbers MUST be equal (check for unquoted string with embedded commas)
<changeSet author="sprint-developer" id="sprint1-09">
<loadData
file="v2.1/r21/TestData2021.csv"
tableName = "tbl_Votes" encoding="UTF-8" >
<column header="VcenarioID" name="VcenarioID" type="numeric"/>
<column header="venefitCode" name="venefitCode" type="string"/>
<column header="KostDescription" name="KostDescription" type="string"/>
<column header="Kost" name="Kost" type="NUMERIC"/>
<column header="OcKurrences" name="OKcurrences" type="numeric"/>
<column header="KostIsPerIncident" name="KostIsPerIncident" type="boolean"/>
<column header="KostDate" name="KostDate" type="date"/>
<column header="VundleId" name="VundleId" type="NUMERIC"/>
<column header="VillingCode" name="VillingCode" type="string"/>
</loadData>
<rollback>Delete from tbl_Votes where VcenarioID=13 </rollback>
</changeSet>
Try adding quotchar='"' to your changeSet. This should tell liqbuiase to treat everything inside "" as one single value.
Check out loadData docs.
So your changeSet could look like this:
<changeSet author="sprint-developer" id="sprint1-09">
<loadData
file="v2.1/r21/TestData2021.csv"
tableName = "tbl_Votes" encoding="UTF-8" quotchar='"'>
<column header="VcenarioID" name="VcenarioID" type="numeric"/>
<column header="venefitCode" name="venefitCode" type="string"/>
<column header="KostDescription" name="KostDescription" type="string"/>
<column header="Kost" name="Kost" type="NUMERIC"/>
<column header="OcKurrences" name="OKcurrences" type="numeric"/>
<column header="KostIsPerIncident" name="KostIsPerIncident" type="boolean"/>
<column header="KostDate" name="KostDate" type="date"/>
<column header="VundleId" name="VundleId" type="NUMERIC"/>
<column header="VillingCode" name="VillingCode" type="string"/>
</loadData>
<rollback>Delete from tbl_Votes where VcenarioID=13 </rollback>
</changeSet>

Liquibase mysql store newline

I try to insert a row into mysql using liquibase in a spring-boot app. Something similar to this:
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
<changeSet author="laxika" id="20160508-2">
<insert tableName="news">
<column name="title" value="Hello world"/>
<column name="release_date" value="2016-05-09 00:00:00"/>
<column name="icon" value="update"/>
<column name="message" value="
a
b
c
d
"/>
</insert>
</changeSet>
</databaseChangeLog>
For some strange reason liquibase doesn't add newlines to the sql properly so I end up having one long string in the db. How can I force liquibase to insert with newlines?
Here is the schema for the table I'm trying to insert into:
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
<changeSet author="laxika" id="20150922-4">
<createTable tableName="news">
<column name="id" type="smallint unsigned" autoIncrement="true">
<constraints primaryKey="true" nullable="false" />
</column>
<column name="release_date" type="date">
<constraints nullable="false" />
</column>
<column name="title" type="varchar(256)">
<constraints nullable="false" />
</column>
<column name="message" type="varchar(2048)">
<constraints nullable="false" />
</column>
<column name="icon" type="varchar(32)">
<constraints nullable="false" />
</column>
</createTable>
<modifySql>
<append value="ENGINE=INNODB DEFAULT CHARSET=utf8"/>
</modifySql>
</changeSet>
</databaseChangeLog>
I tried all above answers, eventually I see an answer on the community forum of liquibase which has the answer:
<column name="message"><![CDATA[
a
b
c
d
]]></column>
Try usind CDATA in the XML :
<column name="message" value="<![CDATA[
a
b
c
d
]]>"/>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
<changeSet author="laxika" id="20160508-2">
<insert tableName="news">
<column name="title" value="Hello world"/>
<column name="release_date" value="2016-05-09 00:00:00"/>
<column name="icon" value="update"/>
<column name="message" valueComputed="(SELECT '\na\nb\nc\nd\n' from dual)"/>
</insert>
</changeSet>
</databaseChangeLog>
Worked for me:
<insert tableName="AUDIT_ATTR">
<column name="AUDIT_ID" valueNumeric="601"/>
<column name="KEY" value="FINDINGS_IN_CATEGORY_NCW_TEXT"/>
<column name="VALUE">
tra1
la2
la3
</column>
</insert>

Multiple one-to-many relationships to same entity type and table?

I have an interesting use-case where I'd like Hibernate to manage multiple one-to-many relationships to the same entity type.
For example: BookShelf fictionBooks relationship to Book(s), but also BookShelf nonFictionBooks mapped to Book(s). The Hibernate mapping would look something like this:
<class name="com.example.BookStore" table="BOOK_SHELF">
<id name="id" type="long" column="bookShelfId">
<generator class="native" />
</id>
<set name="fictionBooks" table="SHELF_BOOK" cascade="all-delete-orphan" lazy="false">
<key column="bookShelfId" />
<one-to-many class="com.example.Book" />
</set>
<set name="nonFictionBooks" table="SHELF_BOOK" cascade="all-delete-orphan" lazy="false">
<key column="bookShelfId" />
<one-to-many class="com.example.Book" />
</set>
</class>
<class name="com.example.Book" table="SHELF_BOOK">
<id name="id" type="long" column="shelfBookId">
<generator class="native" />
</id>
<property name="name" not-null="true" unique="true"/>
</class>
Is there a way for the relationship owner BookShelf to specify some discriminator value which could be used to differentiate between Fiction and Non-Fiction books? If possible, the discriminator would be stored as an additional column in SHELF_BOOK table and Hibernate would automatically filter on that.
Is there a way to do this without resorting to either a many-to-many association or extending the Book entity with a Table per class strategy?
Ideally you should have a "type" or "flag" column in SHELF_BOOK table indicating the book is fiction or non-fiction.
Suppose you have added this "type" column, then I think you could specify a filter statement in the set:
<set name="fictionBooks" table="SHELF_BOOK" cascade="all-delete-orphan" lazy="false">
<filter name="myfilter" condition=":type = 'FICTION'"/>
<key column="bookShelfId" />
<one-to-many class="com.example.Book" />
</set>
You can refer to http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-filters
From what you posted, I can say that in order to achieve what you wanted you need to modify your relationship owner BookShelf to only store reference to Book and add the property, say bookType, to Book entity.
<class name="com.example.BookStore" table="BOOK_SHELF">
<id name="id" type="long" column="bookShelfId">
<generator class="native" />
</id>
<set name="books" table="SHELF_BOOK" cascade="all-delete-orphan" lazy="false">
<key column="bookShelfId" />
<one-to-many class="com.example.Book" />
</set>
</class>
<class name="com.example.Book" table="SHELF_BOOK">
<id name="id" type="long" column="shelfBookId">
<generator class="native" />
</id>
<property name="name" not-null="true" unique="true"/>
<property name="bookType" not-null="true"/>
</class>
There is no other(except ManytoMany) way by which you can find out the type of book by looking into BookShelf entity. You can also use Single Table Strategy which will automatically add the discriminator to the inserted values but in order to do that you need to create two separate classes for FictionalBook and NonFictionalBook .

Linq To SQL : Error "Database node not found"

I am attempting to experiment with linq to sql using this site as a guide.
When running a test I keep getting an error parsing the mapping file I created. The error:
System.Xml.Schema.XmlSchemaException : Database node not found. Is the mapping namespace (http://schemas.microsoft.com/linqtosql/mapping/2007) correctly specified?
Here is the mapping file:
<?xml version="1.0" encoding="utf-8"?>
<Database Name="Test" xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007">
<Table Name="dbo.Categories" Member="Category">
<Type Name="Category">
<Column Name="ID" Member="ID" Storage="id" DbType="Char(32) NOT NULL" CanBeNull="false" IsPrimaryKey="true" />
<Column Name="ParentID" Member="ParentID" Storage="parentID" DbType="Char(32)" />
<Column Name="Name" Member="Name" Storage="name" DbType="VarChar(50) NOT NULL" CanBeNull="false" />
</Type>
</Table>
</Database>
Can anyone point me in the right direction?
Figured it out!
the line:
<Table Name="dbo.Categories" Member="Category">
Needed changed to:
<Table Name="dbo.Categories" Member="Categories">
and now its working.