Oracle 18c:
Test #1:
The following query works as expected. It selects values from XML (the XML is a clob column via a view).
Query:
select
cast(substr(extractvalue(a.column_value,'/Subtype/SubtypeCode'),1,255) as number(9,0)) as subtype_code,
substr(extractvalue(a.column_value,'/Subtype/SubtypeName'),1,255) as subtype_name,
substr(extractvalue(a.column_value,'/Subtype/FieldInfos/SubtypeFieldInfo/FieldName'),1,255) as field_name,
substr(extractvalue(a.column_value,'/Subtype/FieldInfos/SubtypeFieldInfo/DomainName'),1,255) as domain_name
from
sde.gdb_items_vw
cross join
xmlsequence(xmltype(definition).extract('/DETableInfo/Subtypes/Subtype')) a --https://community.oracle.com/tech/developers/discussion/4499629/at-what-version-did-the-table-keyword-for-table-collection-expressions-become-optional
where
name = 'INFRASTR.EVENTS_ONLY_1_ARRAY_VALUE'
SUBTYPE_CODE SUBTYPE_DESCRIPTION FIELD_NAME DOMAIN_NAME
------------ -------------------------------- ---------- --------------
0 ACTIVE TRANSPORTATION ACTIVITY ACTIVITY_ATN_1
1 GEODETIC CONTROL SURVEY MONUMENT ACTIVITY ACTIVITY_GCSM
2 MUNICIPAL STRUCTURES (BRIDGES) ACTIVITY ACTIVITY_MS
XML:
<?xml version="1.0" encoding="UTF-8"?>
<DETableInfo xmlns:typens="http://www.esri.com/schemas/ArcGIS/10.7" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="typens:DETableInfo">
<CatalogPath>\INFRASTR.BC_EVENTS</CatalogPath>
<Name>INFRASTR.BC_EVENTS</Name>
<ChildrenExpanded>false</ChildrenExpanded>
<DatasetType>esriDTTable</DatasetType>
<DSID>60337</DSID>
<Versioned>false</Versioned>
<CanVersion>true</CanVersion>
<ConfigurationKeyword />
<RequiredGeodatabaseClientVersion>10.0</RequiredGeodatabaseClientVersion>
<HasOID>true</HasOID>
<OIDFieldName>OBJECTID</OIDFieldName>
<GPFieldInfoExs xsi:type="typens:ArrayOfGPFieldInfoEx">
<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">
<Name>OBJECTID</Name>
<AliasName>OBJECTID</AliasName>
<ModelName>OBJECTID</ModelName>
<FieldType>esriFieldTypeOID</FieldType>
<IsNullable>false</IsNullable>
<DomainFixed>true</DomainFixed>
<Required>true</Required>
<Editable>false</Editable>
</GPFieldInfoEx>
<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">
<Name>ASSET_CLASS</Name>
<AliasName>ASSET_CLASS</AliasName>
<ModelName>ASSET_CLASS</ModelName>
<FieldType>esriFieldTypeSmallInteger</FieldType>
<DefaultValueNumeric>2</DefaultValueNumeric>
<IsNullable>true</IsNullable>
</GPFieldInfoEx>
<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">
<Name>ACTIVITY</Name>
<AliasName>ACTIVITY</AliasName>
<ModelName>ACTIVITY</ModelName>
<FieldType>esriFieldTypeString</FieldType>
<IsNullable>true</IsNullable>
</GPFieldInfoEx>
</GPFieldInfoExs>
<CLSID>{7A566981-C114-11D2-8A28-006097AFF44E}</CLSID>
<EXTCLSID />
<RelationshipClassNames xsi:type="typens:Names" />
<AliasName />
<ModelName />
<HasGlobalID>false</HasGlobalID>
<GlobalIDFieldName />
<RasterFieldName />
<ExtensionProperties xsi:type="typens:PropertySet">
<PropertyArray xsi:type="typens:ArrayOfPropertySetProperty" />
</ExtensionProperties>
<SubtypeFieldName>ASSET_CLASS</SubtypeFieldName>
<DefaultSubtypeCode>2</DefaultSubtypeCode>
<Subtypes xsi:type="typens:ArrayOfSubtype">
<Subtype xsi:type="typens:Subtype">
<SubtypeName>ACTIVE TRANSPORTATION</SubtypeName>
<SubtypeCode>0</SubtypeCode>
<FieldInfos xsi:type="typens:ArrayOfSubtypeFieldInfo">
<SubtypeFieldInfo xsi:type="typens:SubtypeFieldInfo">
<FieldName>ACTIVITY</FieldName>
<DomainName>ACTIVITY_ATN_1</DomainName>
</SubtypeFieldInfo>
</FieldInfos>
</Subtype>
<Subtype xsi:type="typens:Subtype">
<SubtypeName>GEODETIC CONTROL SURVEY MONUMENT</SubtypeName>
<SubtypeCode>1</SubtypeCode>
<FieldInfos xsi:type="typens:ArrayOfSubtypeFieldInfo">
<SubtypeFieldInfo xsi:type="typens:SubtypeFieldInfo">
<FieldName>ACTIVITY</FieldName>
<DomainName>ACTIVITY_GCSM</DomainName>
</SubtypeFieldInfo>
</FieldInfos>
</Subtype>
<Subtype xsi:type="typens:Subtype">
<SubtypeName>MUNICIPAL STRUCTURES (BRIDGES)</SubtypeName>
<SubtypeCode>2</SubtypeCode>
<FieldInfos xsi:type="typens:ArrayOfSubtypeFieldInfo">
<SubtypeFieldInfo xsi:type="typens:SubtypeFieldInfo">
<FieldName>ACTIVITY</FieldName>
<DomainName>ACTIVITY_MS</DomainName>
</SubtypeFieldInfo>
</FieldInfos>
</Subtype>
</Subtypes>
<ControllerMemberships xsi:type="typens:ArrayOfControllerMembership" />
<EditorTrackingEnabled>false</EditorTrackingEnabled>
<CreatorFieldName />
<CreatedAtFieldName />
<EditorFieldName />
<EditedAtFieldName />
<IsTimeInUTC>false</IsTimeInUTC>
<ChangeTracked>false</ChangeTracked>
<FieldFilteringEnabled>false</FieldFilteringEnabled>
<FilteredFieldNames xsi:type="typens:Names" />
</DETableInfo>
Screenshot from the application.
Test #2:
Regarding the 3rd and 4th columns in the query:
In the first test, the <FieldInfos...> array only had a single value: ACTIVITY.
However, in this next test, the <FieldInfos...> array has multiple values: ACTIVITY and STRATEGY. So when I run the same query, it will fail because it can't return multiple values for a single column.
Query:
select
cast(substr(extractvalue(a.column_value,'/Subtype/SubtypeCode'),1,255) as number(9,0)) as subtype_code,
substr(extractvalue(a.column_value,'/Subtype/SubtypeName'),1,255) as subtype_name,
substr(extractvalue(a.column_value,'/Subtype/FieldInfos/SubtypeFieldInfo/FieldName'),1,255) as field_name,
substr(extractvalue(a.column_value,'/Subtype/FieldInfos/SubtypeFieldInfo/DomainName'),1,255) as domain_name
from
sde.gdb_items_vw
cross join
xmlsequence(xmltype(definition).extract('/DETableInfo/Subtypes/Subtype')) a
where
name = 'INFRASTR.EVENTS_MULTIPLE_ARRAY_VALUES'
Error:
ORA-19025: EXTRACTVALUE returns value of only one node
19025. 00000 - "EXTRACTVALUE returns value of only one node"
*Cause: Given XPath points to more than one node.
*Action: Rewrite the query so that exactly one node is returned.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<DETableInfo xmlns:typens="http://www.esri.com/schemas/ArcGIS/10.7" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="typens:DETableInfo">
<CatalogPath>\INFRASTR.BC_EVENTS</CatalogPath>
<Name>INFRASTR.BC_EVENTS</Name>
<ChildrenExpanded>false</ChildrenExpanded>
<DatasetType>esriDTTable</DatasetType>
<DSID>60337</DSID>
<Versioned>false</Versioned>
<CanVersion>true</CanVersion>
<ConfigurationKeyword />
<RequiredGeodatabaseClientVersion>10.0</RequiredGeodatabaseClientVersion>
<HasOID>true</HasOID>
<OIDFieldName>OBJECTID</OIDFieldName>
<GPFieldInfoExs xsi:type="typens:ArrayOfGPFieldInfoEx">
<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">
<Name>OBJECTID</Name>
<AliasName>OBJECTID</AliasName>
<ModelName>OBJECTID</ModelName>
<FieldType>esriFieldTypeOID</FieldType>
<IsNullable>false</IsNullable>
<DomainFixed>true</DomainFixed>
<Required>true</Required>
<Editable>false</Editable>
</GPFieldInfoEx>
<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">
<Name>ASSET_CLASS</Name>
<AliasName>ASSET_CLASS</AliasName>
<ModelName>ASSET_CLASS</ModelName>
<FieldType>esriFieldTypeSmallInteger</FieldType>
<DefaultValueNumeric>2</DefaultValueNumeric>
<IsNullable>true</IsNullable>
</GPFieldInfoEx>
<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">
<Name>ACTIVITY</Name>
<AliasName>ACTIVITY</AliasName>
<ModelName>ACTIVITY</ModelName>
<FieldType>esriFieldTypeString</FieldType>
<IsNullable>true</IsNullable>
</GPFieldInfoEx>
<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">
<Name>STRATEGY</Name>
<AliasName>TEST_TEXT_FIELD</AliasName>
<ModelName>STRATEGY</ModelName>
<FieldType>esriFieldTypeString</FieldType>
<IsNullable>true</IsNullable>
</GPFieldInfoEx>
</GPFieldInfoExs>
<CLSID>{7A566981-C114-11D2-8A28-006097AFF44E}</CLSID>
<EXTCLSID />
<RelationshipClassNames xsi:type="typens:Names" />
<AliasName />
<ModelName />
<HasGlobalID>false</HasGlobalID>
<GlobalIDFieldName />
<RasterFieldName />
<ExtensionProperties xsi:type="typens:PropertySet">
<PropertyArray xsi:type="typens:ArrayOfPropertySetProperty" />
</ExtensionProperties>
<SubtypeFieldName>ASSET_CLASS</SubtypeFieldName>
<DefaultSubtypeCode>2</DefaultSubtypeCode>
<Subtypes xsi:type="typens:ArrayOfSubtype">
<Subtype xsi:type="typens:Subtype">
<SubtypeName>ACTIVE TRANSPORTATION</SubtypeName>
<SubtypeCode>0</SubtypeCode>
<FieldInfos xsi:type="typens:ArrayOfSubtypeFieldInfo">
<SubtypeFieldInfo xsi:type="typens:SubtypeFieldInfo">
<FieldName>ACTIVITY</FieldName>
<DomainName>ACTIVITY_ATN_1</DomainName>
</SubtypeFieldInfo>
<SubtypeFieldInfo xsi:type="typens:SubtypeFieldInfo">
<FieldName>STRATEGY</FieldName>
<DomainName>STRATEGY</DomainName>
</SubtypeFieldInfo>
</FieldInfos>
</Subtype>
<Subtype xsi:type="typens:Subtype">
<SubtypeName>GEODETIC CONTROL SURVEY MONUMENT</SubtypeName>
<SubtypeCode>1</SubtypeCode>
<FieldInfos xsi:type="typens:ArrayOfSubtypeFieldInfo">
<SubtypeFieldInfo xsi:type="typens:SubtypeFieldInfo">
<FieldName>ACTIVITY</FieldName>
<DomainName>ACTIVITY_GCSM</DomainName>
</SubtypeFieldInfo>
<SubtypeFieldInfo xsi:type="typens:SubtypeFieldInfo">
<FieldName>STRATEGY</FieldName>
<DomainName>STRATEGY</DomainName>
</SubtypeFieldInfo>
</FieldInfos>
</Subtype>
<Subtype xsi:type="typens:Subtype">
<SubtypeName>MUNICIPAL STRUCTURES (BRIDGES)</SubtypeName>
<SubtypeCode>2</SubtypeCode>
<FieldInfos xsi:type="typens:ArrayOfSubtypeFieldInfo">
<SubtypeFieldInfo xsi:type="typens:SubtypeFieldInfo">
<FieldName>ACTIVITY</FieldName>
<DomainName>ACTIVITY_MS</DomainName>
</SubtypeFieldInfo>
<SubtypeFieldInfo xsi:type="typens:SubtypeFieldInfo">
<FieldName>STRATEGY</FieldName>
<DomainName>STRATEGY</DomainName>
</SubtypeFieldInfo>
</FieldInfos>
</Subtype>
</Subtypes>
<ControllerMemberships xsi:type="typens:ArrayOfControllerMembership" />
<EditorTrackingEnabled>false</EditorTrackingEnabled>
<CreatorFieldName />
<CreatedAtFieldName />
<EditorFieldName />
<EditedAtFieldName />
<IsTimeInUTC>false</IsTimeInUTC>
<ChangeTracked>false</ChangeTracked>
<FieldFilteringEnabled>false</FieldFilteringEnabled>
<FilteredFieldNames xsi:type="typens:Names" />
</DETableInfo>
Screenshot from the application.
Question:
How can I only return a single value from the the <FieldInfos...> array: the value where FieldName = ACTIVITY?
EXTRACTVALUE is deprecated. Use XMLTABLE with the XPATH /DETableInfo/Subtypes/Subtype/FieldInfos/SubtypeFieldInfo[FieldName="ACTIVITY"] to filter to only get the ACTIVITY values and then go back up the hierarchy to get the sub-type code and name:
SELECT x.*
FROM /*sde.*/gdb_items_vw i
CROSS APPLY XMLTABLE(
'/DETableInfo/Subtypes/Subtype/FieldInfos/SubtypeFieldInfo[FieldName="ACTIVITY"]'
PASSING XMLTYPE(i.definition)
COLUMNS
SubType_Code NUMBER PATH './../../SubtypeCode',
SubType_Name VARCHAR2(255) PATH './../../SubtypeName',
Field_Name VARCHAR2(255) PATH './FieldName',
Domain_Name VARCHAR2(255) PATH './DomainName'
) x
WHERE i.name = 'INFRASTR.EVENTS_ONLY_1_ARRAY_VALUE'
Which, for the sample data, outputs:
SUBTYPE_CODE
SUBTYPE_NAME
FIELD_NAME
DOMAIN_NAME
0
ACTIVE TRANSPORTATION
ACTIVITY
ACTIVITY_ATN_1
1
GEODETIC CONTROL SURVEY MONUMENT
ACTIVITY
ACTIVITY_GCSM
2
MUNICIPAL STRUCTURES (BRIDGES)
ACTIVITY
ACTIVITY_MS
db<>fiddle here
Related
In React-Admin (v 4.2.4) I'm using 3 resources for a specific view (as showed in the following image also if there's a fourth table).
In my JS file I have this component:
export const RichiestaMerceModifica = () => {
return (
<Edit actions={false} resource="richieste_merce_intestazioni">
<SimpleForm toolbar={<CustomToolbar />}>
<List actions={false} pagination={false}>
<ReferenceManyField reference="richieste_merce_dettagli" target="id_rm" source="id">
<Datagrid>
<TextField source="id_rm" />
<ReferenceField source="id_prod" reference="prodotti_acquisto" label="Prodotto">
<TextField source="nome" />
</ReferenceField>
<ReferenceField source="id_prod" reference="prodotti_acquisto" label="Descrizione" link={false}>
<TextField source="descr" />
</ReferenceField>
<TextField source="qta" label="Q.ta" />
<ReferenceField reference="prodotti_acquisto" source="id_prod" label="Imp. unitario" link={false}>
<FunctionField render={record => `${record.imp} €`} />
</ReferenceField>
<BooleanField source="ordinato" />
</Datagrid>
</ReferenceManyField>
</List>
</SimpleForm>
</Edit>
);
}
All required fields are shown correctly but in the List there are all records from richieste_merce_dettagli resource (not only the correct ones as expected, having defined target="id_rm" source="id").
In the following image is shown the RichiestaMerceModifica Component and I'm in the view for ID 5 so in the List should be only products where "id rm" is 5.
In Admin component I have added
<Resource name="richieste_merce_dettagli" />
<Resource name="richieste_merce_intestazioni" options={{ label: 'Richieste Merce' }} list={RichiesteMerceList} icon={AddCircleOutline} create={RichiestaMerceNuovo} edit={RichiestaMerceModifica} />
<Resource name="prodotti_acquisto" options={{ label: 'Prodotti acquisto' }} list={ProdottiAcquistoList} icon={Summarize} create={ProdottoAcquistoNuovo} edit={ProdottoAcquistoModifica} />
Where is my mistake?
You're not supposed to use a <List> component inside an <Edit> component. <List> and <Edit> are page components, and there can be only one per page.
The code should work without it:
export const RichiestaMerceModifica = () => {
return (
<Edit actions={false} resource="richieste_merce_intestazioni">
<SimpleForm toolbar={<CustomToolbar />}>
- <List actions={false} pagination={false}>
<ReferenceManyField reference="richieste_merce_dettagli" target="id_rm" source="id">
<Datagrid>
<TextField source="id_rm" />
<ReferenceField source="id_prod" reference="prodotti_acquisto" label="Prodotto">
<TextField source="nome" />
</ReferenceField>
<ReferenceField source="id_prod" reference="prodotti_acquisto" label="Descrizione" link={false}>
<TextField source="descr" />
</ReferenceField>
<TextField source="qta" label="Q.ta" />
<ReferenceField reference="prodotti_acquisto" source="id_prod" label="Imp. unitario" link={false}>
<FunctionField render={record => `${record.imp} €`} />
</ReferenceField>
<BooleanField source="ordinato" />
</Datagrid>
</ReferenceManyField>
- </List>
</SimpleForm>
</Edit>
);
}
How can I add custom attribute in mxCell tag of mxgraph? I want to add value2="customValue"
<mxGraphModel dx="872" dy="535" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" background="#ffffff">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="wfState_1" value2="customValue" style="strokeColor:red" vertex="1" parent="1">
<mxGeometry x="50" y="110" width="120" height="70" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
I'm try to make the code below dynamic as there can be different names for the 'name' attribute in the page 'node'.
When I run the code below it returns the error 'XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *''
I feel my main issue is in the line
'C.value('(/level1/level2/template/page/#name)[sql:variable("#Counter")]','NVARCHAR(MAX)') AS [Page Name]'
where I am trying to make '#counter' variable dynamic.
Does anyone have any solutions please?
XML FOR ID 9371
<level1>
<level2>
<template width="594" height="500">
<page Cid="1" name="Test Page Name" colour="-3355393">
<image Cid="8" x="432" y="8" w="148" h="95" KeyImage="32861" Ratio="y" />
<formattedText Cid="14" x="9" y="22" w="253" h="38">
<p>
<p>
Text
</p>
</p>
</formattedText>
</page>
<page Cid="6" name="Properties">
<formattedText Cid="7" x="200" y="148" w="208" h="228">
<p>
<p>
<t>Created by </t>
<t b="b">Joe Bloggs</t>
</p>
<p />
<p>
<t>Date published 30/05/2017</t>
</p>
</formattedText>
</page>
</template>
</level2>
</level1>
RESULTS FROM SQL Query
** Present Result
Page Name | Demographics
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Test Page Name | <page Cid="1" name="Test Page Name" colour="-3355393"><image Cid="8" x="432" y="8" w="148" h="95" KeyImage="32861" Ratio="y" /><formattedText Cid="14" x="9" y="22" w="253" h="38"><p><p>Text</p></p> </formattedText></page>
Test Page Name | <page><formattedText Cid="7" x="200" y="148" w="208" h="228"><p><p> <t>Created by </t><t b="b">Joe Bloggs</t></p><p /><p><t>Date published 30/05/2017</t> </p></formattedText></page>
** Desired Result
Page Name | Demographics
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Test Page Name | <page Cid="1" name="Test Page Name" colour="-3355393"><image Cid="8" x="432" y="8" w="148" h="95" KeyImage="32861" Ratio="y" /><formattedText Cid="14" x="9" y="22" w="253" h="38"><p><p>Text</p></p> </formattedText></page>
Properties | <page><formattedText Cid="7" x="200" y="148" w="208" h="228"><p><p> <t>Created by </t><t b="b">Joe Bloggs</t></p><p /><p><t>Date published 30/05/2017</t> </p></formattedText></page>
DECLARE #TableName VARCHAR(40),
#opxml AS XML,
#hDoc AS INT,
#SQL NVARCHAR (MAX)
SELECT #opxml =
a.[filedata]
FROM [database].[dbo].[xmlfile2] a
where [Id] = 9371
DECLARE #Counter INT
DECLARE #MaxNo INT
SET #Counter=1
SET #MaxNo=(SELECT
COUNT(CAST('<page>' + CAST(C.query('./child::node()') as nvarchar(max)) + '</page>' as xml))
FROM #opxml.nodes('/level1/level2/template/page') AS T(C))
WHILE ( #Counter <= #MaxNo)
BEGIN
SELECT
C.value('(/level1/level2/template/page/#name)[sql:variable("#Counter")]','NVARCHAR(MAX)') AS
[Page Name],
CAST('<page>' + CAST(C.query('./child::node()') as nvarchar(max)) + '</page>' as xml) AS [Page_XML]
, ROW_NUMBER() OVER (ORDER BY t.c)
FROM #opxml.nodes('/level1/level2/template/page') AS T(C)
SET #Counter = #Counter + 1
END
I think
SELECT
C.value('#name','NVARCHAR(MAX)') AS [Page Name],
C.query('<page>{node()}</page>') AS [Page_XML],
ROW_NUMBER() OVER (ORDER BY t.c)
FROM #opxml.nodes('/level1/level2/template/page') AS T(C)
might suffice to produce the wanted result without the need for a WHILE loop.
I think the original problem with the long path inside of value() (e.g. C.value('(/level1/level2/template/page/#name)[sql:variable("#Counter")]','NVARCHAR(MAX)')) is due to the static type checking of XQuery in SQL server and to avoid it you basically need to add another predicate that ensures the type checker knows a single value is returned e.g. C.value('(/level1/level2/template/page/#name)[sql:variable("#Counter")][1]','NVARCHAR(MAX)')
For me, the code
DECLARE #opxml AS XML
SET #opxml = N'<level1>
<level2>
<template width="594" height="500">
<page Cid="1" name="Test Page Name" colour="-3355393">
<image Cid="8" x="432" y="8" w="148" h="95" KeyImage="32861" Ratio="y" />
<formattedText Cid="14" x="9" y="22" w="253" h="38">
<p>
<p>
Text
</p>
</p>
</formattedText>
</page>
<page Cid="6" name="Properties">
<formattedText Cid="7" x="200" y="148" w="208" h="228">
<p>
<p>
<t>Created by </t>
<t b="b">Joe Bloggs</t>
</p>
<p />
<p>
<t>Date published 30/05/2017</t>
</p>
</p>
</formattedText>
</page>
</template>
</level2>
</level1>'
SELECT
C.value('#name','NVARCHAR(MAX)') AS [Page Name],
C.query('<page>{node()}</page>') AS [Page_XML],
ROW_NUMBER() OVER (ORDER BY t.c)
FROM #opxml.nodes('/level1/level2/template/page') AS T(C)
produces the table
Page Name Page_XML (Kein Spaltenname)
Test Page Name <page><image Cid="8" x="432" y="8" w="148" h="95" KeyImage="32861" Ratio="y" /><formattedText Cid="14" x="9" y="22" w="253" h="38"><p><p>
Text
</p></p></formattedText></page> 1
Properties <page><formattedText Cid="7" x="200" y="148" w="208" h="228"><p><p><t>Created by </t><t b="b">Joe Bloggs</t></p><p /><p><t>Date published 30/05/2017</t></p></p></formattedText></page> 2
so at least the Page_Name seems to be easily populated by using e.g. C.value('#name','NVARCHAR(MAX)') AS [Page Name]
I have a xml data column. The XML data contains a form with different page headers. Each page has radio type values. I need to pick the value from one page and its values.
I need the value 'id' from Page topic='Outreach' under that, Question value="Type of Outreach", in that i need the id="1" value and also i need the id value from Question value="Reason for Assessment".
Below is the sample xml data.
<Test name="Assessment " header="" logoimg="" background="" icon="" firstPage="1" allow_abort="1" is_um="0" is_hidden="0" do_only="1" status="1" locale_id="0" version="74" category_id="150011" maxQuestionID="37" id="10234" force_start="0" user_name=" ggg bbb">
<PAGE topic="Outreach " progress="5" background="" headerid="" footerid="" flush_concepts="1" lastPage="false" id="1">
<BRANCH_CONDITION>
<NEXT_PAGE id="2" />
</BRANCH_CONDITION>
<QUESTION value="Type of Outreach " defaultvalue="" style="" tooltip="" read_only="0" usability="5" prefer_concept="0" type="radio" validation="0" id="1" pagename="Outreach ">
<OPTIONS>
<OPTION value="Outbound Telephone " id="1" url="" score="0" />
<OPTION value="Inbound Telephone" id="2" url="" score="0" />
<OPTION value="In Person" id="3" url="" score="0" />
</OPTIONS>
</QUESTION>
<QUESTION value="Reason for Assessment " defaultvalue="" style="" tooltip="" read_only="0" usability="5" prefer_concept="0" type="radio" validation="0" id="2" pagename="Outreach ">
<OPTIONS>
<OPTION value="New" id="1" url="" score="0" />
<OPTION value="Annual" id="2" url="" score="0" />
<OPTION value="Triggering Event " id="3" url="" score="0" />
<OPTION value="LOC Review" id="4" url="" score="0" />
</OPTIONS>
</QUESTION>
I tried the following sql.
SELECT TABLE.META_DATA.value('(/QUESTION//id/node())[1]','int') as outReach
,TABLE.META_DATA.value('(/QUESTION//id/node())[1]','int') as ReasonForAssessment
FROM Table
Below is my expected result
+----------+---------------------+
| Outreach | ReasonForAssessment |
+----------+---------------------+
| 1 | 2 |
Several issues:
QUESTION is not the root of the XML so you must use // or walk down tree from root: /Test/PAGE/QUESTION/.
Adjust XPath to search by attribute with # prefix and not node search as id is an attribute (not child node) of QUESTION.
Adjust node index, [#], to return the corresponding #id attribute value.
Adjusted SQL:
SELECT TABLE.META_DATA.value('(//QUESTION/#id)[1]','int') as outReach
, TABLE.META_DATA.value('(//QUESTION/#id)[2]','int') as ReasonForAssessment
FROM Table;
-- outReach ReasonForAssessment
-- 1 2
Alternatively use bracketed conditionals for columns:
SELECT TABLE.META_DATA.value('(/Test/PAGE/QUESTION[#value=''Type of Outreach '']/#id)[1]','int') as outReach
, TABLE.META_DATA.value('(/Test/PAGE/QUESTION[#value=''Reason for Assessment '']/#id)[1]','int') as ReasonForAssessment
FROM Table;
-- outReach ReasonForAssessment
-- 1 2
Oracle 11g2.
For example:
select XMLType(
'<main>
<article>
<title>1.txt</title>
<type>market</type>
<author>
<name>J. Smith</name>
<age>32</age>
</author>
</article>
<comment>For information</comment>
</main>').getStringVal() from dual;
Could you help me modify this select statement ?
I'd like to get varchar output as :
<title>1.txt</title>
<type>market</type>
<author>
<name>J. Smith</name>
<age>32</age>
</author>
unfortunately, using extract('/main/article') as:
select XMLType(
'<main>
<article>
<title>1.txt</title>
<type>market</type>
<author>
<name>J. Smith</name>
<age>32</age>
</author>
</article>
<comment>For information</comment>
</main>').extract('/main/article').getStringVal() from dual;
lose format of the text (all output in one row).
Thank you in advance.
You can do this (well, including the article node) via XMLTABLE and XMLSERIALISE to do the pretty printing, e.g.:
Query
with sample_data as (select XMLType(
'<main>
<article>
<title>1.txt</title>
<type>market</type>
<author>
<name>J. Smith</name>
<age>32</age>
</author>
</article>
<comment>For information</comment>
</main>') xdata from dual)
select xmlserialize(document x.col1 as varchar2(4000) indent size = 2)
from sample_data sd
cross join xmltable('/main/article'
passing sd.xdata
columns col1 xmltype path '.') x;
Result
<article>
<title>1.txt</title>
<type>market</type>
<author>
<name>J. Smith</name>
<age>32</age>
</author>
</article>
As #Boneist shows you can use xmlserialize() for the formatting, but as you only seem to have a single article node in your document you can still use your extract():
select xmlserialize(document XMLType(
'<main>
<article>
<title>1.txt</title>
<type>market</type>
<author>
<name>J. Smith</name>
<age>32</age>
</author>
</article>
<comment>For information</comment>
</main>').extract('/main/article')
as varchar2(200) indent) as article
from dual;
Or you can use an XMLQuery:
select xmlserialize(document xmlquery('/main/article'
passing XMLType(
'<main>
<article>
<title>1.txt</title>
<type>market</type>
<author>
<name>J. Smith</name>
<age>32</age>
</author>
</article>
<comment>For information</comment>
</main>')
returning content)
as varchar2(200) indent) as article
from dual;
ARTICLE
--------------------------------------------------------------------------------
<article>
<title>1.txt</title>
<type>market</type>
<author>
<name>J. Smith</name>
<age>32</age>
</author>
</article>