Найти текст элемента в XML, который содержит пространство имен с GPath - PullRequest
0 голосов
/ 01 октября 2011

Эй, я хотел бы найти данный текст в 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>

Так что в этом примере я хотел бы найти текст: «Некоторая служба».

Я пытался с Xpath, но не смог заставить это работать. Я также попробовал с Gpath, и все, что я мог получить, это все тексты в одной длинной строке.

Как бы вы сделали это в GPath и / или XPath?

Ответы [ 4 ]

2 голосов
/ 01 октября 2011

Попробуйте этот XPath:

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

Он вернет все элементы, которые содержат текстовый узел с Some Service

1 голос
/ 02 октября 2011

Использование 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()

Поскольку имена элементов в вашем образце уникальны, это можно сделать с помощью или без регистрации пространств имен.

1 голос
/ 01 октября 2011

После регистрации привязок префиксов к соответствующим пространствам имен используйте :

  /*/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>
0 голосов
/ 02 октября 2011

Использование 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();
...