0

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

4 回答 4

2

试试这个 XPath:

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

它将返回包含文本节点的所有元素Some Service

于 2011-10-01T17:20:07.037 回答
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>
于 2011-10-01T19:22:10.337 回答
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()

由于示例中的元素名称是唯一的,因此无论是否注册名称空间都可以完成。

于 2011-10-02T16:02:03.637 回答
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();
于 2011-10-02T15:56:48.957 回答