I am using a servlet(servlet1) via a GET method from httpurlconnection() function in order to get the XML generated by an another servlet(servlet2) connected to a postgreSQL Database.
The XML generated by the servlet2 via the statement:
select query_to_xml('select * from test', true, false, '');
I initialize an httpurlconnection() from servlet1 to servlet2 and I stored in a string "response1" the output like that:
String inputLine;
StringBuffer response1 = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response1.append(inputLine);
}
in.close();
//The output in console
System.out.println(response1.toString());
The XML is stored in the string "response1" as:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link type="text/css" rel="stylesheet" href="/pro/inc/form.css;jsessionid=D965FA3338EC4E88F6F7AA0B64308446" />
</head>
<body>
<p><alltests_00_with_defects xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
<n5>a</n5>
<n4>b</n4>
<n3>c</n3>
<n2>d</n2>
<n1>e</n1>
<row>
<row>
<n5>a</n5>
<n4>b</n4>
<n3>c</n3>
<n2>d</n2>
<n1>e</n1>
<row>
</html>
Until here, it's cool!!
Now, I am looking for a solution that can convert BACK the XML generated to data values.
Any ideas?
Related
My delete statement is not working i am trying to delete duplicate row if user have entered more than one product_id and user_id but the delete is not working at all.
I tried entering one row multiple time and hasNext returns true, goes over if but doesn't execute delete and alert
Code:
<%--
Document : cart
Created on : Apr 24, 2020, 3:43:01 PM
Author : user
--%>
<%#page import="java.sql.CallableStatement"%>
<%#page import="java.sql.SQLException"%>
<%#page import="java.sql.ResultSet"%>
<%#page import="java.sql.DriverManager"%>
<%#page import="java.sql.Statement"%>
<%#page import="java.sql.Connection"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<%
String username=(String)session.getAttribute("username");
String product_id=request.getParameter("id");
Connection con=null;
Statement stmt=null;
Statement stmt1=null;
Statement stmt2=null;
try{
Class.forName("oracle.jdbc.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:XE","admin","admin");
}
catch(ClassNotFoundException e){
System.out.println("Class not found :"+e.getMessage());
}
try{
int user_id=0;
stmt=con.createStatement();
stmt1=con.createStatement();
stmt2=con.createStatement();
//check for duplicate rows to avoid user adding to cart the same item again.
ResultSet rs=stmt.executeQuery("SELECT user_id FROM users where user_name='"+username+"'");
while(rs.next()){
user_id=Integer.valueOf(rs.getString(1));
System.out.println(user_id);
}
stmt1.executeUpdate("INSERT INTO transaction (user_id,product_id) values('"+user_id+"','"+product_id+"')");
ResultSet rs_check=stmt.executeQuery("SELECT '"+user_id+"','"+product_id+"', COUNT(*) occurences from transaction GROUP BY '"+user_id+"','"+product_id+"' HAVING COUNT(*) > 1 ");
//check for duplicate rows after insert and then delete that row
System.out.println(rs_check.next());//1)false
boolean hasNext=rs_check.next();
if(hasNext){
//stmt2.executeUpdate("delete from transaction where user_id='"+user_id+"' and product_id='"+product_id+"'");
CallableStatement ctmt=con.prepareCall("{call delete_dup(?,?)}");
ctmt.setInt(1,user_id);
ctmt.setInt(2,Integer.valueOf(product_id));
ctmt.execute();
%><script>alert("you have added the item before?");</script><%
}
}
catch(SQLException e){
System.out.println("SQL Exception: "+e.getMessage());
}
%>
</body>
</html>
Try to add a commit after the insert to check if this works like :
con.commit();
If this solve the problem you have to set : con.setAutoCommit(true);, if you don't want to use Oracle commit/rollback feature.
I have a following Kotlin object type with default null value for a field:
data class Field(
val content: String? = null,
val field: String = ""
)
Then I try to pass the object:
val myObject = Field(field = "something")
to the mustache template:
<!DOCTYPE ...>
<html>
<head>
<meta .../>
</head>
<body ...">
{{#myObject}}
{{#content}}
{{.}}<br/>
{{/content}}
{{#field}}
{{.}}<br/>
{{/field}}
{{/myObject}}
</body>
</html>
And after filling the template I receive an exception: No key, method or field with name 'content' on line ...
I cannot get what can be wrong
may be you should define the "" for the content default for the problem?
I have a table where a column is stored in a xml format so it is possible do display it on other projects with formatted text.
But I need to convert it to a single line without tags.
I have tried to use value() method and nodes(), but didn't quite managed to make it work...
This is the example of the content of the column i want to format.
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css">p {font-family: sans-serif;font-size: 8.25pt;margin: 0px;}</style> </head> <body> <p>VALUE I WANT TO GET </p> </body> </html>
SELECT Id, Description, Value FROM MyTable
Where Value is the column with stored xml..
Is there a way to get the body content without any tags in a single line?
THE COLUMN IS NOT XML TYPE BUT VARCHAR(MAX) TYPE
If your HTML value always same format, please try following scripts together:
Converting HTML into supported format for querying with value () and node()
Declare #x nvarchar (4000) = '<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css">p {font-family: sans-serif;font-size: 8.25pt;margin: 0px;}</style> </head> <body> <p>VALUE I WANT TO GET </p> </body> </html>'
select #x = replace (#x,
'<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ',
''
);
SELECT #x = REPLACE(#x, 'xmlns=', 'xmlns:i=');
--Print #x;
Actual select query on converted XML
select xmldata,
Cast (x2.c.query('data(body/p)') as nvarchar (100)) as HtmlBody
From
(select convert (xml, #x ) as xmldata) as x
cross apply xmldata.nodes('html') as x2(c)
Additional:
Querying direct table, hope this would work if you replace #temp with your table name and column names accordingly
Declare #Temp table (ID bigint, xmlvalue nvarchar(4000) );
Declare #x nvarchar (4000) = '<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css">p {font-family: sans-serif;font-size: 8.25pt;margin: 0px;}</style> </head> <body> <p>VALUE I WANT TO GET </p> </body> </html>';
Insert into #Temp
VALUES (101, #x);
select x.*,
Cast (x2.c.query('data(body/p)') as nvarchar (100)) as HtmlBody
From (
select ID, CAST(REPLACE(
(replace (xmlvalue,
'<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ',
'') ),
'xmlns=',
'xmlns:i='
) AS xml) as xmldata
from #Temp
) as x
CROSS APPLY xmldata.nodes('html') as x2(c)
go
If you think it's difficult to manager in future, create scalar function with same logic - Consider recommendations in terms of performance when using custom scalar functions
You can do something similar to this:
Language is VB.Net.
Dim XMLDoc As New XmlDocument
Dim dt As DataTable = GetData() <-- GetData() is where you load the data using your query
XMLDoc.Load(dt.Rows(0).Item("Value").ToString)
Dim TextThatIWant As string = XMLDoc.SelectSingleNode("/html/body/p").InnerText
Try it like this:
DECLARE #YourValue VARCHAR(MAX)=
'<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css">p {font-family: sans-serif;font-size: 8.25pt;margin: 0px;}</style> </head> <body> <p>VALUE I WANT TO GET </p> </body> </html>';
WITH XMLNAMESPACES(DEFAULT 'http://www.w3.org/1999/xhtml')
SELECT CONVERT(xml,#YourValue,2).value('(/html/body/p/text())[1]','varchar(1000)');
The idea in short:
We can not CAST() the string to XML, due to the <!DOCTYPE>, but we can use CONVERT() with the parameter 2. This will return your string as XML.
Against the XML we can use .value()
As your XML declares a default namespace we declare this namespace using WITH XMLNAMESPACES
Attention: HTML is far not as strict as XML. If you cannot be sure, that your HTML is XHTML actually (which means, that it follows the much stricter rules of XML), it can be dangerous to rely on XML methods. Luckily the namespace points to xhtml...
If not, this might work in all your tests, but break in production at any time...
My problem is that when I execute my stored procedure, the XML data is not saved in my table. I do not receive any error code :((
My xml file:
if you have problem reading my xml file below click here to view it online (more understandable)
<?xml version="1.0"?>
<q:quakeml xmlns="http://quakeml.org/xmlns/bed/1.2" xmlns:catalog="http://anss.org/xmlns/catalog/0.1" xmlns:q="http://quakeml.org/xmlns/quakeml/1.2">
<eventParameters publicID="quakeml:earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.quakeml">
<event catalog:datasource="ak" catalog:eventsource="ak" catalog:eventid="11554973" publicID="quakeml:earthquake.usgs.gov/earthquakes/feed/v1.0/detail/ak11554973.quakeml"><description><type>earthquake name</type><text>5km WSW of North Pole, Alaska</text></description><origin catalog:datasource="ak" catalog:dataid="ak11554973" catalog:eventsource="ak" catalog:eventid="11554973" publicID="quakeml:earthquake.usgs.gov/realtime/product/origin/ak11554973/ak/1429291513635/product.xml"><time><value>2015-04-17T17:13:49.000Z</value></time><longitude><value>-147.4577</value></longitude><latitude><value>64.731</value></latitude><depth><value>10700</value><uncertainty>1300</uncertainty></depth><originUncertainty><horizontalUncertainty>400</horizontalUncertainty><preferredDescription>horizontal uncertainty</preferredDescription></originUncertainty><quality><usedPhaseCount>6</usedPhaseCount><standardError>0.04</standardError></quality><evaluationMode>automatic</evaluationMode><creationInfo><creationTime>2015-04-17T17:25:13.635Z</creationTime><version>1</version></creationInfo></origin><magnitude catalog:datasource="ak" catalog:dataid="ak11554973" catalog:eventsource="ak" catalog:eventid="11554973" publicID="quakeml:earthquake.usgs.gov/realtime/product/origin/ak11554973/ak/1429291513635/product.xml#magnitude"><mag><value>0.7</value></mag><type>ml</type><originID>quakeml:earthquake.usgs.gov/realtime/product/origin/ak11554973/ak/1429291513635/product.xml</originID><evaluationMode>automatic</evaluationMode><creationInfo><creationTime>2015-04-17T17:25:13.635Z</creationTime></creationInfo></magnitude><preferredOriginID>quakeml:earthquake.usgs.gov/realtime/product/origin/ak11554973/ak/1429291513635/product.xml</preferredOriginID><preferredMagnitudeID>quakeml:earthquake.usgs.gov/realtime/product/origin/ak11554973/ak/1429291513635/product.xml#magnitude</preferredMagnitudeID><type>earthquake</type><creationInfo><agencyID>ak</agencyID><creationTime>2015-04-17T17:25:13.635Z</creationTime><version>1</version></creationInfo></event>
<event catalog:datasource="nn" catalog:eventsource="nn" catalog:eventid="00490511" publicID="quakeml:earthquake.usgs.gov/earthquakes/feed/v1.0/detail/nn00490511.quakeml"><description><type>earthquake name</type><text>28km SW of Lovelock, Nevada</text></description><origin catalog:datasource="nn" catalog:dataid="nn00490511" catalog:eventsource="nn" catalog:eventid="00490511" publicID="quakeml:earthquake.usgs.gov/realtime/product/origin/nn00490511/nn/1429291355376/product.xml"><time><value>2015-04-17T17:09:21.386Z</value></time><longitude><value>-118.7333</value></longitude><latitude><value>40.0237</value></latitude><depth><value>0</value><uncertainty>5313.5</uncertainty></depth><originUncertainty><horizontalUncertainty>8118.1</horizontalUncertainty><preferredDescription>horizontal uncertainty</preferredDescription></originUncertainty><quality><usedPhaseCount>13</usedPhaseCount><usedStationCount>11</usedStationCount><standardError>0.1417</standardError><azimuthalGap>245.03</azimuthalGap><minimumDistance>0.591</minimumDistance></quality><evaluationMode>manual</evaluationMode><creationInfo><agencyID>NN</agencyID><creationTime>2015-04-17T17:22:35.376Z</creationTime><version>490511</version></creationInfo></origin><magnitude catalog:datasource="nn" catalog:dataid="nn00490511" catalog:eventsource="nn" catalog:eventid="00490511" publicID="quakeml:earthquake.usgs.gov/realtime/product/origin/nn00490511/nn/1429291355376/product.xml#magnitude"><mag><value>1.95</value><uncertainty>0.23</uncertainty></mag><type>ml</type><stationCount>8</stationCount><originID>quakeml:earthquake.usgs.gov/realtime/product/origin/nn00490511/nn/1429291355376/product.xml</originID><evaluationMode>manual</evaluationMode><creationInfo><agencyID>NN</agencyID><creationTime>2015-04-17T17:22:35.376Z</creationTime></creationInfo></magnitude><preferredOriginID>quakeml:earthquake.usgs.gov/realtime/product/origin/nn00490511/nn/1429291355376/product.xml</preferredOriginID><preferredMagnitudeID>quakeml:earthquake.usgs.gov/realtime/product/origin/nn00490511/nn/1429291355376/product.xml#magnitude</preferredMagnitudeID><type>earthquake</type><creationInfo><agencyID>nn</agencyID><creationTime>2015-04-17T17:22:35.376Z</creationTime><version>490511</version></creationInfo></event>
<creationInfo><creationTime>2015-04-17T17:32:50.000Z</creationTime></creationInfo>
</eventParameters>
</q:quakeml>
My stored procedure:
ALTER PROCEDURE [dbo].[InsertXML]
#xml XML
AS
BEGIN
WITH XMLNAMESPACES ('http://quakeml.org/xmlns/quakeml/1.2' as q,
default 'http://quakeml.org/xmlns/bed/1.2')
INSERT INTO quake_tbl
SELECT
tim.value('(text())[1]','VARCHAR(300)') AS times,
latitud.value('(text())[1]','numeric(18,6)') AS latitude ,
longitud.value('(text())[1]','numeric(18,6)') AS longitude ,
deph.value('(text())[1]','numeric(18,6)') AS depth ,
magnitud.value('(text())[1]','numeric(18,6)') AS magnitude ,
typomag.value('(type/text())[1]','VARCHAR(300)') AS mag_type,
placee.value('(text())[1]','VARCHAR(300)') AS place ,
typo.value('(text())[1]','VARCHAR(300)') AS type
FROM
#xml.nodes('/q:quakeml/eventParameters/event') as TEMPTABLE(quakedetails)
CROSS APPLY
TEMPTABLE.quakedetails.nodes('origin/time/value') AS timess(tim)
CROSS APPLY
TEMPTABLE.quakedetails.nodes('origin/latitude/value') AS lat(latitud)
CROSS APPLY
TEMPTABLE.quakedetails.nodes('origin/longitude/value') AS long(longitud)
CROSS APPLY
TEMPTABLE.quakedetails.nodes('origin/depth/value') AS dep(deph)
CROSS APPLY
TEMPTABLE.quakedetails.nodes('magnitude/mag/value') AS magn(magnitud)
CROSS APPLY
TEMPTABLE.quakedetails.nodes('magnitude/type') AS typmag(typomag)
CROSS APPLY
TEMPTABLE.quakedetails.nodes('origin/description/text') AS plac(placee)
CROSS APPLY
TEMPTABLE.quakedetails.nodes('origin/description/type') AS typ(typo)
END
My vb.net code behind in asp.net:
Imports System.IO
Imports System.Data
Imports System.Configuration
Imports System.Data.SqlClient
Partial Class UploadXml
Inherits System.Web.UI.Page
Protected Sub UploadXML(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn_upload.Click
Dim fileName As String = Path.GetFileName(FileUpload1.PostedFile.FileName)
Dim filePath As String = Server.MapPath("~/Uploads/") & fileName
FileUpload1.SaveAs(filePath)
Dim xml As String = File.ReadAllText(filePath)
Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand("InsertXML")
cmd.Connection = con
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#xml", xml)
con.Open()
cmd.CommandTimeout = 120
cmd.ExecuteNonQuery()
con.Close()
End Using
End Using
End Sub
End Class
My markup in html:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="UploadXml.aspx.vb" Inherits="UploadXml" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:FileUpload ID = "FileUpload1" runat = "server" />
<asp:Button ID="btn_upload" Text="Upload XML" runat="server" />
</div>
</form>
</body>
</html>
When you debug your SELECT statement, it becomes obvious that the last two CROSS APPLY statements don't return any data:
CROSS APPLY
TEMPTABLE.quakedetails.nodes('origin/description/text') AS plac(placee)
CROSS APPLY
TEMPTABLE.quakedetails.nodes('origin/description/type') AS typ(typo)
So check your XML - somehow that path origin/description doesn't seem to exist.
If you check your XML, you'll see that the <description> node is directly under the <event> node - not under <origin> - so use this:
CROSS APPLY
TEMPTABLE.quakedetails.nodes('description/text') AS plac(placee)
CROSS APPLY
TEMPTABLE.quakedetails.nodes('description/type') AS typ(typo)
and then your query should work.
Update: you could optimize your query by not doing as many CROSS APPLY calls to .nodes() functions - limit yourself to just the <origin> nodes, and then grab the individual bits and pieces inside that node using XPath expression - try this query:
; WITH XMLNAMESPACES ('http://quakeml.org/xmlns/quakeml/1.2' as q,
default 'http://quakeml.org/xmlns/bed/1.2')
SELECT
Times = XOrigin.value('(time/value)[1]', 'varchar(100)'),
Latitude = XOrigin.value('(latitude/value)[1]', 'numeric(18,6)'),
Longitude = XOrigin.value('(longitude/value)[1]', 'numeric(18,6)'),
Depth = XOrigin.value('(depth/value)[1]', 'numeric(18,6)'),
Magnitude = XEvent.value('(magnitude/value)[1]', 'numeric(18,6)'),
Mag_Type = XEvent.value('(magnitude/type/value)[1]', 'varchar(100)'),
Place = XEvent.value('(description/text)[1]', 'varchar(100)'),
[Type] = XEvent.value('(description/type)[1]', 'varchar(100)')
FROM
#xml.nodes('/q:quakeml/eventParameters/event') as XT1(XEvent)
CROSS APPLY
XEvent.nodes('origin') AS XT2(XOrigin)
This is the SELECT only - does that run faster?
I have the following XML which I load via XDocument.Load(uri) or XElement.Load(uri). I am having trouble getting a collection of <asset> elements via LINQ.
Here is a snippet of the XML I'm trying to query:
<assetCollection xmlns="tag:aisle7.net,2009:/api/1.0">
<title>All Assets</title>
<description>Collection containing all assets in the system</description>
<resourcePath>/us/assets/~all</resourcePath>
<link rel="self" href="http://web.aisle7.net/api/1.0/us/assets/~all?apikey=1234567890&Format=XML" />
<link rel="first" href="http://web.aisle7.net/api/1.0/us/assets/~all?apikey=1234567890&Format=XML" />
<link rel="next" href="http://web.aisle7.net/api/1.0/us/assets/~all?apikey=1234567890&Format=XML&page=2" />
<link rel="last" href="http://web.aisle7.net/api/1.0/us/assets/~all?apikey=1234567890&Format=XML&page=66" />
<updated>2011-03-01T19:01:49.667Z</updated>
<assets>
<asset>
<title>Homeopathy</title>
<resourcePath>/us/assets/toc/homeopathy</resourcePath>
<link rel="alternate" href="http://web.aisle7.net/api/1.0/us/assets/toc/homeopathy?apikey=1234567890&Format=XML" />
<updated>2011-03-01T19:01:49.667Z</updated>
</asset>
<asset>
<title>What Is Homeopathy?</title>
<resourcePath>/us/assets/generic/what-is-homeopathy_13615_1</resourcePath>
<link rel="alternate" href="http://web.aisle7.net/api/1.0/us/assets/generic/what-is-homeopathy_13615_1?apikey=1234567890&Format=XML" />
<updated>2011-03-01T19:00:17.680Z</updated>
</asset>
...
And here is the code I'm trying to use:
Dim uri As String = HttpUtility.UrlDecode(ConfigurationManager.AppSettings("Aisle7_Index_Url"))
Dim assets = (From a In XElement.Load(uri)
.Element("assets")
.Elements("asset")
Select a)
For Each asset In assets
Console.WriteLine(asset)
Next
Try
Dim assets = From a In XElement.Load(uri).Descendants("asset") Select a
or
Dim assets = From a In XDocument.Load(uri).Root.Element("assets").Elements("asset") Select a
Here's the version using xml literal syntax:
Dim xml = XElement.Load(uri)
Dim q = From a In xml.<assets>...<asset>
Select a