ผลลัพธ์ XPath เป็นสตริงว่าง

ต่อไปนี้เป็นไฟล์ XML ของฉัน

<xyzevent xmlns="http://www.xyz.com/common/xyzevent/v1" xmlns:xsi="http://www.w3.org2001XMLSchema-instance">
<header>
 ----
</header>
<subscription xmlns="http://www.xyz.com/common/xyzevent/source/v1">
  <sender></sender>
  <receiver>
    <clientsubscription>
        <servicemap>nanna</servicemap>
    </clientsubscription>
  </receiver>
</subscription> 
</xyzevent>

เมื่อฉัน budila org.w3c.dom.Document จาก XML นี้และใช้ XPathExperssion กับนิพจน์

/xyzevent/subscription/receiver/clientsubscription/servicemap/text()

ผลลัพธ์เป็นสตริงว่าง นิพจน์อาจมีปัญหาอะไร

ขอบคุณ


person Pokuri    schedule 26.08.2011    source แหล่งที่มา


คำตอบ (4)


นั่นเป็นเพราะว่าเอกสาร XML ของคุณใช้เนมสเปซ XPath น่ารำคาญมากกับเนมสเปซ เพื่อยืนยันสิ่งนี้ ให้ตัด xmlns=http://.../v1 สองตัวออกจากเอกสารและเรียกใช้นิพจน์ XPath ของคุณอีกครั้งกับไฟล์ XML ที่ไม่มีเนมสเปซและไม่สามารถตรวจสอบได้ มันจะเข้ากัน

สิ่งที่เกิดขึ้นคือนิพจน์ XPath ของคุณพยายามเลือก /xyzevent เมื่อเอกสารของคุณมี {http://.../v1}:xyzevent ซึ่งไม่เหมือนกัน

มีหลายวิธีในการแก้ไขปัญหานี้ วิธีที่เหมาะสมคือการตั้งค่า NamespaceContext เพื่อให้คุณสามารถใช้สัญลักษณ์ prefix:localName ในนิพจน์ XPath ของคุณและแก้ไขคำนำหน้าให้เป็น URI ที่ถูกต้อง มีการประกาศสั้นๆ เกี่ยวกับเรื่องนี้ใน xerces docs และอื่นๆ อีกมากมาย ที่อื่นใน StackOverflow มีคำอธิบายโดยละเอียดที่ ibm.com

NamespaceContext ของคุณจะมีการแมปสองรายการ (หรือมากกว่า):

{
    event => http://www.xyz.com/common/xyzevent/v1
    source => http://www.xyz.com/common/xyzevent/source/v1
}

นิพจน์ XPath ของคุณจะกลายเป็น /event:xyzevent/source:subscription/source:receiver/.../text()

วิธีแก้ปัญหา น่ารังเกียจ คุณสามารถเขียนนิพจน์ xpath ใหม่เพื่อเลือกโดยใช้ฟังก์ชัน local-name():

/*[local-name()='xyzevent']/*[local-name()='subscription'/ ...

ในกรณีนี้ นิพจน์จะจับคู่องค์ประกอบใดๆ ที่มีชื่อในเครื่องคือ xyzevent โดยไม่คำนึงถึง URI เนมสเปซ

person Barend    schedule 26.08.2011
comment
หลังจากลบ xmlns=http://.../v1 สิ่งนี้จากทั้งสองที่ ฉันสามารถรับค่าได้ แต่คุณช่วยอธิบายวิธีสร้าง NamespaceContext ให้ฉันได้ไหมเมื่อเรามีทั้งค่าเนมสเปซในเอกสาร... - person Pokuri; 26.08.2011
comment
@Pokuri ลงทะเบียนคำนำหน้าสองคำแยกกันใน NamespaceContext ของคุณ เช่น event และ source พร้อม URI ที่เหมาะสมสำหรับแต่ละรายการ นิพจน์ XPath ของคุณจะกลายเป็น /event:xyzevent/source:subscription/source:receiver/... - person Barend; 26.08.2011
comment
แต่ NamespaceContext คาดหวังหนึ่ง namespaceURI และคำนำหน้าอย่างน้อยหนึ่งรายการ แล้วฉันจะส่ง NamespaceContext สองตัวไปยัง XPath.setNamespaceContext(namespaceContext); ได้อย่างไร วิธี - person Pokuri; 26.08.2011
comment
ตัวอย่างบน stackoverflow.com /questions/914013/ ครอบคลุมสิ่งนี้ - person Barend; 26.08.2011
comment
ลิงค์ที่มีประโยชน์จริงๆ ขอบคุณมาก. - person Pokuri; 26.08.2011

XML ของคุณมีเนมสเปซเริ่มต้น: xmlns="http://www.xyz.com/common/xyzevent/v1" ดังนั้น คุณต้องกำหนดมันในกลไก XML/XPath ของคุณ

หรือใช้ XPath นี้:

/*[local-name() = 'xyzevent']
    /*[local-name() = 'subscription']
        /*[local-name() = 'receiver']
            /*[local-name() = 'clientsubscription']
                /*[local-name() = 'servicemap']
                    /text()
person Kirill Polishchuk    schedule 26.08.2011

xyzevent เป็นองค์ประกอบรากของคุณ ดังนั้นคุณเพียงแค่ต้องใช้ "/subscription/receiver/clientsubscription/servicemap/text()"

person Koraktor    schedule 26.08.2011

ฉันประเมินการแสดงออกของคุณในลิงค์ต่อไปนี้:

http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

และดูเหมือนว่าจะเลือก "แนนนา"

person suat    schedule 26.08.2011