Getting XML into a SQLite3 database using Python 3 - python-3.x

I've been trying to get data from a specifix XML file into a SQLite3 database using ElementTree. The XML has the following structure:
<?xml version="1.0" encoding="UTF-8" ?>
<chat xmlns="http://test.org/net/1.3">
<event sender="Frank" time="2016-02-03T22:58:19+01:00" />
<message sender="Karen" time="2016-02-03T22:58:19+01:00">
<div>
<span>Hello Frank</span>
</div>
</message>
<message sender="Frank" time="2016-02-03T22:58:39+01:00">
<div>
<span>Hi there Karen</span>
</div>
<div>
<span>I'm back from New York</span>
</div>
</message>
<message sender="Karen" time="2016-02-03T22:58:56+01:00">
<div>
<span>How are you doing?</span>
<span>Everything OK?</span>
</div>
</message>
</chat>
For each message or event I create a record in the database with the following columns: sender, time, message. The following code is used to process the XML:
import xml.etree.ElementTree as ET
import sqlite3 as lite
con = None
con = lite.connect('dbtest.db')
cur = con.cursor()
xmlfile = 'test.xml'
tree = ET.parse(xmlfile)
root = tree.getroot()
for m in root.findall('./*'):
msg = m.find('.')
msg.tag = 'div'
sender = str(m.get('sender'))
time = m.get('time')
message = str(ET.tostring(msg))
print('Sender: ' + sender)
print('Time: ' + time)
print('HTML: ' + message)
print()
query = ("INSERT INTO chat('time', 'sender', 'message') VALUES(?,?,?)")
values = (time, sender, message)
with con:
cur = con.cursor()
cur.execute(query, values)
if con:
con.close()
This results in several problems.
First of all I don't get the result I want. The "message" should be what's inside the message tag, not including the enclosing message tag, now renamed to div. This is what I should get:
<div>
<span>Hi there Karen</span>
</div>
<div>
<span>I'm back from New York</span>
</div>
Or maybe this:
<div><span>Hi there Karen</span></div><div><span>I'm back from New York</span></div>
Instead I get this:
b'<div xmlns:ns0="http://test.org/net/1.3" sender="Karen" time="2016-02-03T22:58:19+01:00">\n\t\t<ns0:div>\n\t\t\t<ns0:span>Hello Frank</ns0:span>\n\t\t</ns0:div>\n\t</div>\n\t'
So I'm trying to "fix" this, by removing the b' etc, but I hope there is a better method. And removing that starting b' works, but I can't get rid of the \t and \n somehow, using string replace.
Question
How can I get proper XML data into the table without all those escape characters?

So, ElementTree.tostring returns a byte object by default, not a string. So when you print it out, you're seeing that byte object's serialized form, when what you expected and want is a string. I didn't look into it but I suspect that the sqlite binding will insert byte objects as BLOB and strings as TEXT values into the database and that byte by byte they end up being identical.
Anyways, to print out the xml in a more human readable form like you want:
import xml.etree.ElementTree as ET
rawxml='''<?xml version="1.0" encoding="UTF-8" ?>
<chat xmlns="http://test.org/net/1.3">
<event sender="Frank" time="2016-02-03T22:58:19+01:00" />
<message sender="Karen" time="2016-02-03T22:58:19+01:00">
<div>
<span>Hello Frank</span>
</div>
</message>
<message sender="Frank" time="2016-02-03T22:58:39+01:00">
<div>
<span>Hi there Karen</span>
</div>
<div>
<span>I'm back from New York</span>
</div>
</message>
<message sender="Karen" time="2016-02-03T22:58:56+01:00">
<div>
<span>How are you doing?</span>
<span>Everything OK?</span>
</div>
</message>
</chat>'''
ns={'msg' : "http://test.org/net/1.3"}
xml = ET.fromstring(rawxml)
for msg in xml.findall("msg:message", ns):
print("Sender: " + msg.get("sender"))
print("Time: " + msg.get("time"))
body=""
for d in msg.findall("msg:div", ns):
body = body + ET.tostring(d, encoding="unicode")
print("Content: " + body)
Note the use of the encoding="unicode" argument to tostring(), which makes it return a string. Adding the XML namespace attributes is just how ElementTree works with them.

Related

Component attributes do not support complex content (mixed C# and markup) error message

I am working on validation on a form in a blazor server application.
I created the component below that I am using
#* Inherits from the original InputText component *#
#inherits InputText
#* Bind the oninput event *#
<input #attributes="AdditionalAttributes"
class="#CssClass"
value="#CurrentValue"
#oninput="EventCallback.Factory.CreateBinder<string>(this, __value => CurrentValueAsString = __value, CurrentValueAsString)" />
#code {
}
I am using the inputTextOnInput in this form
<EditForm EditContext="#EditContext">
<DataAnnotationsValidator />
<div class="mb-5">
<label for="projectnameinput" class="form-label">Name your project*</label>
<InputTextOnInput class="form-control form-control-lg cust #pNameValidation" id="projectnameinput" #bind-value="projectModel.ProjectName" #onkeyup=KeyboardEventHandler />
</div>
</EditForm>
since I created this I started getting the error message below
Component attributes do not support complex content (mixed C# and markup). Attribute: 'class', text: 'form-controlform-control-lgcustpNameValidation
Do you have an idea of what this implies?
You cannot use the class attribute in your new component if you have declared a specific parameter for that.
<InputTextOnInput class="form-control form-control-lg cust #pNameValidation" id="projectnameinput" #bind-value="projectModel.ProjectName" #onkeyup=KeyboardEventHandler />
you need to remove class from above and pass it via CssClass.
For some reason Blazor/Razor don't let you mix text literals and variables within an attribute value. So when you try and do
<InputTextOnInput class="form-control form-control-lg cust #pNameValidation" id="projectnameinput" #bind-value="projectModel.ProjectName" #onkeyup=KeyboardEventHandler />
the class statement is invalid because it contains literals "form-control", "form-control-lg" and "cust" and also a variable "#pNameValidation".
My solution to this problem was to create a little method on a component base class which allows mixing the two things.
public string Class(string classStr, params string[] objStrs)
{
var output = new StringBuilder();
output.Append(classStr);
output.Append(' ');
output.AppendJoin(' ', objStrs);
return output.ToString();
}
now all I have to do is to write my line like this
<InputTextOnInput class="#Class("form-control form-control-lg cust", pNameValidation)" id="projectnameinput" #bind-value="projectModel.ProjectName" #onkeyup=KeyboardEventHandler />
and by using params, you can also just add as many string variables as you want.

Groovy question to read xml and base64decode

I want to modify the incoming message (As shown in the Modified XML) output.
Incoming XML
<xml>
<Body>
<Request>
<Container>
<name>test</name>
<Numbers>
<sn>//base64encodedstring//</sn>
<sn>//base64encodedstring//</sn>
<sn>//base64encodedstring//</sn>
</Numbers>
</Container>
</Request>
</Body>
</xml>
Modified XML
<xml>
<Body>
<Request>
<Container>
<name>test</name>
<Numbers>
<sn>//Decodedstring//</sn>
<sn>//Decodedstring//</sn>
<sn>//Decodedstring//</sn>
</Numbers>
</Container>
</Request>
</Body>
</xml>
As per the answer received: I can create an array of ListOfResults.
def listOfResults = new XmlSlurper()
.parseText(xml)
.Body.Request.Container.Numbers.sn
.collect { new String(it.text().decodeBase64()) }
I can do the following
def data = "<xml><Body><Request><Container><name>test</name><Numbers>"
for (i= 0; i <listOfResults.size(); i++)
{
data = data +"<sn>" +listOfResults[i] + "</sn>";
}
data = data + "<Numbers></Container></Request></Body></xml>";
Modified data
<xml><Body><Request><Container><name>test</name>
<Numbers>
<sn>decoded string</sn>
<sn>decoded string</sn>
<sn>decoded string</sn>
</Numbers> </Container></Request></Body></xml>
Is this the fastest way to do this operation? Is there any other better way?
You should be able to do (assuming your XML is in a string variable called xml):
def listOfResults = new XmlSlurper()
.parseText(xml)
.Body.Request.Container.Numbers.sn
.collect { new String(it.text().decodeBase64()) }

simplesearch modx with date dropdown integration

Iam new to modx(revolution version 2.5.7) and simple search(simplesearch-1.9.2-pl)
I need to add date dropdown (need to fetch results with matching date which is a template variable as type date ) with simplesearch extra in modx plugin. I have attached screenshot of my searchpage for reference. Please help me to solve this.
https://forums.modx.com/thread/95128/advsearch-to-show-search-value-based-on-dropdown-box.
After many painful debugging , got my code working.
[b]My code[/b] ,
[[!AdvSearchForm? &tpl=`AdvanceSearchForm_tpl`]]
</h1>
<h2>Results</h2>
<p>[[!AdvSearch? &parents=`12`&queryHook=`FilterCalenderSnippet` ]]
[b]form tpl (AdvanceSearchForm_tpl) :--[/b]
[code]<form id="[[+advsearch.asId]]_advsea-form" class="advsea-form" action="[[~[[+advsearch.landing]]]]" method="[[+advsearch.method]]">
<fieldset>
<input type="hidden" name="id" value="[[+advsearch.landing]]" />
<input type="hidden" name="asId" value="[[+advsearch.asId]]" />
[[+advsearch.helpLink]]<input type="text" id="[[+advsearch.asId]]_advsea-search" name="[[+advsearch.searchIndex]]" value="[[+advsearch.searchValue]]" />
[[$SeminarCalendarDateChunk]]// give the dropdown of dates,you can put your form elements
[[+advsearch.liveSearch:isnot=`1`:then=`<input type="submit" id="[[+advsearch.asId]]_advsea-submit" name="sub" value="[[%advsearch.search? &namespace=`advsearch` &topic=`default`]]" />`:else`=``]]
</fieldset>
</form>
[[+advsearch.resultsWindow]]
[b]Query Hook snippet(FilterCalenderSnippet)[/b]
[ul]
[li]My Date tv is EventDateTv[/li]
[/ul]
[code]
<?php
$andConditions = array();
// here i need to show events between one given input month. so I did some php to fetch first and last days of given month
if (!empty($_REQUEST['calendar_date'])) {
$dateToTest = $_REQUEST['calendar_date'];// my form element name is calendar_date
$lastday = date('Y-m-t',strtotime($dateToTest));
$andConditions['tv.EventDateTv:>='] = $dateToTest;
$andConditions['tv.EventDateTv:<='] = $lastday ;
}
if (!empty($andConditions)) {
$qhDeclaration = array(
'qhVersion' => '1.3',
'andConditions' => $andConditions
);
$hook->setQueryHook($qhDeclaration);
}
return true;
[/code]`enter code here`

How to upload images in jaggeryjs?

This is my sample HTML code
<html>
<head>
<title>
fileupload
</title>
</head>
<body>
<form action="process.jag" method="post" id="" name="">
<!-- File input filed -->
<input type="file" name="myFile">
<!-- The submit button. It calls the server side function uploadfiles() on click -->
<input type="submit" id="" value="Upload File">
</form>
</body>
</html>
This is my jaggery code
<%
var verb=request.getMethod();
if (verb=='POST'){
var log = new Log();
var file = request.getFile("myFile");
file.move("C:\Users\vatsal ramesh gosar\Desktop\New folder\form\fileUploadUsingJaggery"+file.getName());
response.sendRedirect("https://www.google.com");
}
%>
It is giving a NULL Pointer Exception.
Please help me solve this problem with an efficient code.
request.getFile("myFile") does not represent a physical file, rather it represent a stream to the uploaded file. Hence you cannot "move" it using file.move("/moving/path") function. If you want to save the uploaded file, then use the following code snippet.
var uploadedFile = request.getFile("myFile");
var savedFile = new File("/path/to/save/location/" + uploadedFile.getName());
savedFile.open('w');
savedFile.write(uploadedFile.getStream());
savedFile.close();
In Jaggery documentation I haven't find any way to upload image into the server. But some alternatives there...
You encode the image into base64 encoding, you may use this way too encode the images on base64
$path = 'myfolder/myimage.png';
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
then send the encoded String using POST request using Jaggery.

Get Attribute Values From Child Element With No ID - JQuery

Lets say I have this code:
<div id="Element_1" class="draggable">
<input type="text" placeholder="Enter Your Text Here" style="width:300px;">
</div>
<div id="Element_2" class="draggable">
<textarea placeholder="Enter Your Text Here" style="width:400px;height:200px;"></textarea>
</div>
What I am trying to do is get the element attribute values, from the child of the "div" and also the "Type" (Input/Tagname) so I can store the values in variables.
Currently I can get the element and store in a Var, this is the code I have:
$(".draggable").live("click",function(){
var SelectedID = $(this).attr("id");
$("*").removeClass("selected");
var Element = $("#"+SelectedID,":first-child").addClass("selected").html();
PlaceholderPropValue = $(element).attr("placeholder");
StylesPropValue = $(element).attr("style");
WidthProp = StylesProp.match(/(width:)([0-9].*?)(?=px;)/)[2];
HeightProp = StylesProp.match(/(height:)([0-9].*?)(?=px;)/)[2];
alert(PlaceholderPropValue+ " " +WidthProp+ " " +HeightProp);
});
Thanks!
Carl
Your code is kind of overkill.
.live() is deprecated in jQuery 1.7 and totally removed in 1.9, jquery documentation says you should use .on() instead.
Everything is simple. You can try something like:
$('.draggable').click(function(){
var $element = $(this).children();
var width = parseInt($element.width());
var height = parseInt($element.height());
var placeholder = $element.attr('placeholder');
alert(placeholder+ " " +width+ " " +height);
})
.children() method normally return set of element's children but there are only one in your example, so it's ok.
.width() and .height() returns values like "300px", so we use parseInt() to make int values.
.click(handler) is a shortcut for .on( "click", handler )

Resources