XMLEXISTS
does return true for empty elements, you're just sending it c3.CLASS
, which is a CHAR(1)
column instead of an XMLTYPE
, so it doesn't detect a root element (/
) and returns false.
Here's an example of different ways you can play around with this. I added an XMLTYPE copy of CLASS to c3, and referenced it in the SELECT clause. Try deleting the "z" from the sample data, or the whole CLASS node, and see what happens.
See this similar question for how to write an XPATH query to check if a node is empty.
-- sample data
with xml_test as (select xmltype('<Data><EMPLOYER><SUMMARY><WORKER><RESULT_DETAIL><CLASS>z</CLASS></RESULT_DETAIL></WORKER></SUMMARY></EMPLOYER></Data>') as file_xml from dual)
-- your query
SELECT --case when XMLEXISTS('/' passing by ref c3.class) then 1 else 0 end E_CLASS, /* won't work if CLASS is non-empty */
case when XMLEXISTS('/' passing by ref c3.class_x) then 1 else 0 end E_CLASS_X,
case when XMLEXISTS('/RESULT_DETAIL/CLASS' passing by ref c2.RESULT_DETAIL) then 1 else 0 end E_RD_CLASS,
c3.CLASS,
c3.CLASS_X,
-- but this probably does what you want, detect if CLASS exists and is empty:
case when XMLEXISTS('/CLASS' passing by ref c3.class_x)
and not XMLEXISTS('/CLASS/text()' passing by ref c3.class_x) then 1 else 0 end EMPTY_CLASS
FROM XML_TEST x,
XMLTABLE ('/Data/EMPLOYER'
PASSING x.File_XML
COLUMNS DOSSIER NUMBER(8) PATH 'DOSSIER',
SUMMARY XMLTYPE PATH 'SUMMARY'
) e,
XMLTABLE ('/SUMMARY'
PASSING e.SUMMARY
COLUMNS BEGINDATE DATE PATH 'BEGINDATE',
WORKER XMLTYPE PATH 'WORKER'
) c1,
XMLTABLE ('/WORKER'
PASSING c1.WORKER
COLUMNS NRWORKER NUMBER(7) PATH 'NRWORKER',
RESULT_DETAIL XMLTYPE PATH 'RESULT_DETAIL'
) c2 ,
XMLTABLE ('/RESULT_DETAIL'
PASSING c2.RESULT_DETAIL
COLUMNS CODE CHAR(5) PATH 'CODE',
MINUTES NUMBER(5) PATH 'MINUTES',
CLASS CHAR(1) PATH 'CLASS',
CLASS_X XMLTYPE PATH 'CLASS' -- added an XMLTYPE column with the same data
) c3 ;
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…