2011-10-01 53 views
0

嘿,我想找到一個XML看起來像這樣給定文本:查找元素的XML包含與GPATH命名空間文本

<s:Envelope xmlns:s="http://..."> 
<s:Body> 
<About_ServiceResponse xmlns="http://...> 
<About_ServiceResult xmlns:a="http://> 
<a:businessServiceVersionStructureField> <a:BusinessServiceVersionStructureType>              <a:businessServiceDBVersionNameField>V001</a:businessServiceDBVersionNameField> 
<a:businessServiceVersionNameField>Some Service^V100</a:businessServiceVersionNameField> 
      </a:BusinessServiceVersionStructureType> 
     </a:businessServiceVersionStructureField> 
    </About_ServiceResult> 
    </About_ServiceResponse> 
</s:Body> 
</s:Envelope> 

因此,在這個例子中我想找到文字:「一些服務」。

我已經嘗試過Xpath,但無法讓它工作。我也嘗試過使用Gpath,所有我可以在那裏得到一個長字符串中的所有文本。

如何在GPath或/和XPath中執行此操作?

+0

「我嘗試過使用XPath,但無法使其工作。」你嘗試了什麼XPath表達式,結果如何? – LarsH

回答

2

試試這個XPath:

//*[contains(text(), 'Some Service')] 

這將返回包含與Some Service

+0

好的在這個在線工具中嘗試了XPath,它看起來像返回正確的節點。但它看起來像表達式:「// a:businessServiceVersionNameField [name()]」將會這樣做。 2個表達式的結果之間是否有任何不同? – Nyegaard

1

文本節點註冊前綴的綁定到相應的命名空間之後的所有元素,使用

/*/s:Body 
     /s:About_ServiceResponse 
      /s:About_ServiceResult 
       /a:businessServiceVersionStructureField 
        /a:BusinessServiceVersionStructureType 
         /a:businessServiceVersionNameField 
          /text() 

當此XPath表達式針對fo llowing XML文檔(所提供的一個嚴重畸形的,我不得不花費大量的時間,使之充分形成):

<s:Envelope xmlns:s="http://..."> 
    <s:Body> 
     <About_ServiceResponse xmlns="http://..."> 
      <About_ServiceResult xmlns:a="http://"> 
       <a:businessServiceVersionStructureField> 
        <a:BusinessServiceVersionStructureType> 
         <a:businessServiceDBVersionNameField>V001</a:businessServiceDBVersionNameField> 
         <a:businessServiceVersionNameField>Some Service^V100</a:businessServiceVersionNameField> 
        </a:BusinessServiceVersionStructureType> 
       </a:businessServiceVersionStructureField> 
      </About_ServiceResult> 
     </About_ServiceResponse> 
    </s:Body> 
</s:Envelope> 

究竟想要的文本節點選擇

Some Service^V100 

如果要選擇作爲此文本節點父級的元素,請使用

/*/s:Body 
     /s:About_ServiceResponse 
      /s:About_ServiceResult 
       /a:businessServiceVersionStructureField 
        /a:BusinessServiceVersionStructureType 
         /a:businessServiceVersionNameField 

XSLT - 基於驗證

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:s="http://..." xmlns:a="http://"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "/*/s:Body 
     /s:About_ServiceResponse 
      /s:About_ServiceResult 
       /a:businessServiceVersionStructureField 
        /a:BusinessServiceVersionStructureType 
         /a:businessServiceVersionNameField 
          /text() 
    "/> 
    ======= 
    <xsl:copy-of select= 
    "/*/s:Body 
     /s:About_ServiceResponse 
      /s:About_ServiceResult 
       /a:businessServiceVersionStructureField 
        /a:BusinessServiceVersionStructureType 
         /a:businessServiceVersionNameField 
    "/> 
</xsl:template> 
</xsl:stylesheet> 

當該變換被針對同一XML文檔(以上),所選擇的節點是輸出(使用施加 「=======」 作爲分隔符):

Some Service^V100 
    ======= 
    <a:businessServiceVersionNameField xmlns:a="http://" xmlns="http://..." xmlns:s="http://...">Some Service^V100</a:businessServiceVersionNameField> 
+0

好吧,但然後表達式:// a:businessServiceVersionNameField/text()會給我節點businessServiceVersionNameField的所有元素的文本的權利? – Nyegaard

+0

@Tatewaki:這個表達式*選擇*所有文本節點,其中任何一個都是'a:businessServiceVersionNameField'元素的子節點。然而,使用XPath的僞操作符通常會導致嚴重的低效率(慢),因爲它會導致整個文檔樹(或者一個子樹,如果上下文節點不是頂層節點)被搜索。建議在文檔的結構靜態地知道時避免使用'/ /'。 –

0

使用Groovy XmlSlurper。

def xml = new XmlSlurper().parseText(yourXml).declareNamespace(ns1: 'http://..',ns2:'http://..') 
def theText = xml?.'ns1:Body'?.'ns2:About_ServiceResponse'?.'ns3.About_ServiceResult'?.businessServiceVersionStructureField?.businessServiceVersionNameField.text(); 
1

使用Groovy用的XmlSlurper/GPathResult

def xml = ''' 
<s:Envelope xmlns:s="http://foo"> 
    <s:Body> 
    <About_ServiceResponse xmlns="http://bar"> 
     <About_ServiceResult xmlns:a="http://baz"> 
     <a:businessServiceVersionStructureField> 
      <a:BusinessServiceVersionStructureType> 
      <a:businessServiceDBVersionNameField>V001</a:businessServiceDBVersionNameField> 
      <a:businessServiceVersionNameField>Some Service^V100</a:businessServiceVersionNameField> 
      </a:BusinessServiceVersionStructureType> 
     </a:businessServiceVersionStructureField> 
     </About_ServiceResult> 
    </About_ServiceResponse> 
    </s:Body> 
</s:Envelope>''' 

def envelope = new XmlSlurper().parseText(xml) 
envelope.declareNamespace(s:'http://foo', t:'http://bar', a:'http://baz') 

assert 'Some Service^V100' == envelope.'s:Body'. 
             't:About_ServiceResponse'. 
             't:About_ServiceResult'. 
             'a:businessServiceVersionStructureField'. 
             'a:BusinessServiceVersionStructureType'. 
             'a:businessServiceVersionNameField'.text() 

assert 'Some Service^V100' == envelope.'Body'. 
             'About_ServiceResponse'. 
             'About_ServiceResult'. 
             'businessServiceVersionStructureField'. 
             'BusinessServiceVersionStructureType'. 
             'businessServiceVersionNameField'.text() 

因爲你的樣品中的元素名稱是獨一無二的,它可以有或沒有註冊的命名空間來完成。

相關問題