最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Xpath to get all Child Nodes as XML in Groovy - Stack Overflow

programmeradmin1浏览0评论

I am receiving below XML as request

<orderMessageRequest>
    <wave>wave01</wave>
    <orderLine>
        <orderLineNumber>1</orderLineNumber>
        <dn>123</dn>
        <productId>TestProduct1</productId>
        <attributeValue>
            <name>lotCode</name>
            <value>123</value>
            <name>lotCode1</name>
            <value>1234</value>
        </attributeValue>
    </orderLine>
    <orderLine>
        <orderLineNumber>2</orderLineNumber>
        <dn>4032455365</dn>
        <productId>TestProduct2</productId>
    </orderLine>
</orderMessageRequest>

I am using groovy and XPath to get orderLine as

//orderMessageRequest/orderLine[1] or //orderMessageRequest/orderLine[1]/node()

There are 2 problem i am facing in my code.

  1. Even though i am using [0] or [1] in orderLine path, its returning only first orderLine
  2. Its just returning value not complete node

my code

String processXml( String xml, String xpathQuery ) {
  def xpath = XPathFactory.newInstance().newXPath()
  def builder     = DocumentBuilderFactory.newInstance().newDocumentBuilder()
  def inputStream = new ByteArrayInputStream( xml.bytes )
  def records     = builder.parse(inputStream).documentElement
  def x=xpath.evaluate( xpathQuery, records );
return x;

def x=processXml( testxml, '//orderTuPickConfirmationMessageRequest/orderLine[1]/node()' )

What is wrong here, i am expecting result as based on orderLine[0/1] it should return complete orderLine for eg orderLine[0]

<orderLine>
        <orderLineNumber>1</orderLineNumber>
        <dn>123</dn>
        <productId>TestProduct1</productId>
        <attributeValue>
            <name>lotCode</name>
            <value>123</value>
            <name>lotCode1</name>
            <value>1234</value>
        </attributeValue>
    </orderLine>

I am receiving below XML as request

<orderMessageRequest>
    <wave>wave01</wave>
    <orderLine>
        <orderLineNumber>1</orderLineNumber>
        <dn>123</dn>
        <productId>TestProduct1</productId>
        <attributeValue>
            <name>lotCode</name>
            <value>123</value>
            <name>lotCode1</name>
            <value>1234</value>
        </attributeValue>
    </orderLine>
    <orderLine>
        <orderLineNumber>2</orderLineNumber>
        <dn>4032455365</dn>
        <productId>TestProduct2</productId>
    </orderLine>
</orderMessageRequest>

I am using groovy and XPath to get orderLine as

//orderMessageRequest/orderLine[1] or //orderMessageRequest/orderLine[1]/node()

There are 2 problem i am facing in my code.

  1. Even though i am using [0] or [1] in orderLine path, its returning only first orderLine
  2. Its just returning value not complete node

my code

String processXml( String xml, String xpathQuery ) {
  def xpath = XPathFactory.newInstance().newXPath()
  def builder     = DocumentBuilderFactory.newInstance().newDocumentBuilder()
  def inputStream = new ByteArrayInputStream( xml.bytes )
  def records     = builder.parse(inputStream).documentElement
  def x=xpath.evaluate( xpathQuery, records );
return x;

def x=processXml( testxml, '//orderTuPickConfirmationMessageRequest/orderLine[1]/node()' )

What is wrong here, i am expecting result as based on orderLine[0/1] it should return complete orderLine for eg orderLine[0]

<orderLine>
        <orderLineNumber>1</orderLineNumber>
        <dn>123</dn>
        <productId>TestProduct1</productId>
        <attributeValue>
            <name>lotCode</name>
            <value>123</value>
            <name>lotCode1</name>
            <value>1234</value>
        </attributeValue>
    </orderLine>
Share Improve this question edited Mar 14 at 3:22 keku keku asked Mar 14 at 2:51 keku kekukeku keku 632 silver badges9 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

Using XPath that way is just use Java's APIs in Groovy. But Groovy offers a much simpler interface for working with XML with XmlSlurper. For example, I was able to get this script working with your excerpt:

import groovy.xml.*

String xmlText = """
<orderMessageRequest>
    <wave>wave01</wave>
    <orderLine>
        <orderLineNumber>1</orderLineNumber>
        <dn>123</dn>
        <productId>TestProduct1</productId>
        <attributeValue>
            <name>lotCode</name>
            <value>123</value>
            <name>lotCode1</name>
            <value>1234</value>
        </attributeValue>
    </orderLine>
    <orderLine>
        <orderLineNumber>2</orderLineNumber>
        <dn>4032455365</dn>
        <productId>TestProduct2</productId>
    </orderLine>
</orderMessageRequest>
"""

XmlSlurper slurper = new XmlSlurper()
def xml = slurper.parseText( xmlText )

println("-----Print First Node-----")
println( XmlUtil.serialize(xml.orderLine[0]) )
println("-----Print Second Node-----")
println( XmlUtil.serialize(xml.orderLine[1]) )

println("-----Print All Nodes-----")
xml.orderLine.each { orderLine -> println( XmlUtil.serialize( orderLine ) ) }

println("Done.")

Using XmlSlurper is very similar to XPath, but just easier API-wise.

I also tried out your code, and I got a .xml.sax.SAXParseException; lineNumber: 2; columnNumber: 9; Premature end of file. I never figured out why it wasn't working everything looked in order. There is a typo in the xpath:

//orderTuPickConfirmationMessageRequest/orderLine[1]/node() 

probably you meant //orderToPick....

//orderToPickConfirmationMessageRequest/orderLine[1]/node()

But even after fixing that it still didn't like it. XmlSlurper was able to parse it without issue though so ¯\_(ツ)_/¯

发布评论

评论列表(0)

  1. 暂无评论