在XML中查找包含带有GPath的命名空间的元素的文本

时间:2011-10-01 15:59:52

标签: xml xpath groovy gpath

嘿我想在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”。

我尝试过使用Xpath,但无法使用它。我也尝试过使用Gpath,我只能在一个长字符串中找到所有文本。

您将如何在GPath或/和XPath中执行此操作?

4 个答案:

答案 0 :(得分:2)

试试这个XPath:

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

它将返回包含Some Service

文本节点的所有元素

答案 1 :(得分:1)

在将前缀绑定到相应的命名空间后,使用

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

当针对以下XML文档评估此XPath表达式时(提供的那个表达式严重错误,我不得不花费大量时间使其格式良好):

<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>

答案 2 :(得分: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()

由于样本中的元素名称是唯一的,因此可以在注册或不注册命名空间的情况下完成。

答案 3 :(得分: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();