Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

i'm new to xml DB with Oracle and i'm starting to get my bearings around it but there is one thing that is important that i can't figure to do : i need to identify 1. if an element exist 2. if it is empty

unfortunatly the XMLExists() just mix the two answers.

a small part of my query :

SELECT case when XMLEXISTS('/' passing by ref c3.CLASS) then 1 else 0 end E_CLASS,        
       c3.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'                            
            ) c3 ;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
178 views
Welcome To Ask or Share your Answers For Others

1 Answer

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 ;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...