how to remove namespace from an existing xml subtree in oracle - oracle

I'm facing an issue with removing namespace from existing xml subtree.
For Example: I have a table with 1 field - data type xmltype. One entry is holding this xml:
<Item xmlns="http://www.w3.org/2001/XMLSchema-instance">
<Box>Blaff</Box>
<Door>Steal</Door>
<Chair>Wood</Chair>
</Item>
I would like to remove the namespace - i.e.:
<Item>
<Box>Black-box</Box>
<Door>Steal</Door>
<Chair>Wood</Chair>
</Item>
Do you have any suggestions? - I tried using the UPDATE() function with no luck.
Thank you very much for the help.

One idea is to transform it to a clob, then replace the namespace string and transform it back to xml:
with xtab as (
select xmltype('<Item xmlns="http://www.w3.org/2001/XMLSchema-instance">
<Box>Blaff</Box>
<Door>Steal</Door>
<Chair>Wood</Chair>
</Item>') my_xml from dual)
select xmltype(replace(xmltype.getclobval(my_xml),
' xmlns="http://www.w3.org/2001/XMLSchema-instance"', '')) clo
from xtab;

Related

How do I extract a specific ID in SQL from a XML column?

I have looked at other posts on here but I and still struggling to make it work. For example, here is my XML and I am trying retrieve just the RoleID:
<?xml version="1.0" encoding="utf-16"?>
<C_ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="aaaaaaaa-1111-1111-1111-aaaaaaaaaaaa" t_="Name" a_="U">
<U_ />
<S_>
<C_ id="bbbbbbbb-2222-2222-2222-bbbbbbbbbbbb" t_="NameMembership" a_="C">
<U_>
<F_ n_="NameId" d_="UI">
<N_>cccccccc-3333-3333-ccccccccccccccccc</N_>
</F_>
<F_ n_="RoleId" d_="UI">
<N_>dddddddd-4444-4444-ddddddddddddddddd</N_>
</F_>
</U_>
<S_ />
</C_>
</S_>
</C_>
To confirm, I am looking to retrieve the value
dddddddd-4444-4444-ddddddddddddddddd.
Any help here would be very much appreciated. FYI I am using SQL Server 2012
If you have this XML in a SQL Server variable like this:
DECLARE #SomeVar XML = N'....(your XML here)....';
then you can fetch the value of the node with the n_="RoleId" with this SQL/XQuery:
SELECT
#SomeVar.value('(/C_/S_/C_/U_/F_[#n_="RoleId"])[1]', 'varchar(100)')
UPDATE: if you have an XML column in a table, you'd approach it like this:
DECLARE #xmlTable TABLE (ID INT NOT NULL, XmlData XML);
INSERT INTO #xmlTable (ID, XmlData)
VALUES (1, N'----your XML here----');
SELECT
XC.value('(F_[#n_="RoleId"])[1]', 'varchar(100)')
FROM
#value v
CROSS APPLY
v.XmlData.nodes('/C_/S_/C_/U_') AS XT(XC)
WHERE
v.ID = 1

Multiple conditions in xpath

I am new to xquery and want to add the conditions on activityStatus as 'A' and maritalStatus as "Married" to get gender of person. I have already created query to add conditions individually but am kind of stuck in case to adding multiple conditions. Any pointers will be helpful.
Thanks in advance.
Query to get gender on the basis of Marital Status:
SELECT PersonInfo.gender_1
from personData personData,
xmltable('$personData/Person/personDataCollection/
personData[(maritalStatus=("Married"))]'
passing personData."XMLDATA" as "personData"
columns gender_1 varchar(12) path 'gender'
) PersonInfo
...and the document...
<?xml version="1.0" encoding="UTF-8"?>
<Person>
<activityStatus>A</activityStatus>
<personDataCollection>
<personData>
<personName>
<lastName>ABC</lastName>
<firstName>XYZ</firstName>
</personName>
<addressCollection>
<address>
<line1>123</line1>
<city>QWERTY</city>
<state>ASDF</state>
<postalCode>147852</postalCode>
</address>
</addressCollection>
<maritalStatus>Married</maritalStatus>
<gender>M</gender>
</personData>
</personDataCollection>
</Person>
It sounds like you just want to add a second predicate to your XPath. If that's the case then you were almost done:
$personData/Person[activityStatus="A"]/personDataCollection/personData[maritalStatus="Married"]

Can't get data with a xpath query

how could i get only the rows where the ProcedureID = 6104 in my xml database field?
<CDirData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://Fnet.ESB.Schemas.CentroDirectivo.CDirData">
<ProcedureData xmlns="">
<ProcedureId>6104</ProcedureId>
<CentroDirectivo>SGRP</CentroDirectivo>
</ProcedureData>
<SolicitudData xmlns="">
<SolicitudId>MFom635230432391710791</SolicitudId>
<Status>Iniciado</Status>
I've been trying something like
WITH XMLNAMESPACES (
'http://www.w3.org/2001/XMLSchema-instance' AS "xsi",
'http://www.w3.org/2001/XMLSchema' AS "xsd",
'http://Fnet.ESB.Schemas.CentroDirectivo.CDirData' AS "de")
SELECT [Message].value(
'(/de:CDirData/de:ProcedureData/de:ProcedureId)[1]', 'nvarch
but always returns null rows ...
Thanks in advance
The complication here is the default namespace defined at the root.
One workaround is to define your query in terms of local-name
//*[local-name()='ProcedureId' and text()='6104']

why this XPATH query is not working?

My XML document looks like this
When I run XPATH query //collected_objects, I don't get any nodeset selected. What am I doing wrong? I want to select the whole collected_objects node.
Because your XML document has a XML namespace defined (<oval_system_characteristics xmlns="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5") - you need to include that in your query!
How you can do this depends on what system/programming language you're using. In .NET / C#, you could do this something like this:
// create XmlDocument and load XML file
XmlDocument doc = new XmlDocument();
doc.Load(yourXmlFileNameHere);
// define XML namespace manager and a prefix for the XML namespace used
XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("ns", "http://oval.mitre.org/XMLSchema/oval-system-characteristics-5");
// get list of nodes, based on XPath - using the XML namespace manager
XmlNodeList list = doc.SelectNodes("//ns:collected_objects", mgr);

How to get child of xmlelement in sql query without its name?

In sql server xml column I have xml like this:
<Test>
<Operations>
<Operations type="OperationSend">
<OperationSend>
<ToCompanyId>1</ToCompanyId>
<Date>2011-05-01T00:00:00</Date>
</OperationSend>
</Operations>
<Operations type="OperationSell">
<OperationSell>
<ToCompanyId>33</ToCompanyId>
<Amount>12</Amount>
</OperationSell>
</Operations>
<Operations type="OperationEdit">
<OperationEdit>
<ToCompanyId>12</ToCompanyId>
<Date>2011-11-01T00:00:00</Date>
</OperationEdit>
</Operations>
</Operations>
</Test>
I need to take ToCompanyId from last operation (12). I came to something like this. What should be in ??? when there can be any operation type with ToCompanyId.
select testxml.query('(/Test/Operations/Operations)[last()]/???/ToCompanyId') from dbo.MyXmlTable
You can use *
select testxml.query('(/Test/Operations/Operations)[last()]/*/ToCompanyId').value('.', 'int')
from MyXmlTable
Put node() instead of ???
node() matches all nodes of any kind
Assuming that you have set your xml to be a variable named #x then this is how to get your 12.
select x.header.value('.', 'int')
from #x.nodes('//Test/Operations/Operations[last()]/OperationSend/ToCompanyId')
as x(header)
the query would be slightly different to get from a column of a table but the XPATH would be the same.
select testxml.query('//Test/Operations/Operations[last()]/OperationSend/ToCompanyId') from dbo.MyXmlTable

Resources