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 も試してみましたが、すべてのテキストが 1 つの長い文字列に含まれているだけでした。

GPath または XPath でこれをどのように行いますか?

4

4 に答える 4

2

このXPathを試してください:

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

テキストノードを含むすべての要素を返しますSome Service

于 2011-10-01T17:20:07.037 に答える
1

XmlSlurper/GPathResultでのGroovyの使用

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 に答える
1

プレフィックスのバインディングを対応する名前空間に登録した後、次を使用します

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

この XPath 式が次の 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>
于 2011-10-01T19:22:10.337 に答える
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 に答える