可以使用subsequence
XPath函數,指定subsequence(items, start, length)
從由length
參數指定的項目數start參數位置返回的items
的序列。
你的情況,例如,以獲得10個第一<patient>
節點上,您可以使用:
subsequence(//PatientInfo[1]/Patient,1,10)
如果你想獲得總<Patient>
節點的百分比,可以同時使用subsequence
功能與count
爲了計算總的子節點,並且還需要div
,*
和round
爲了得到一個非浮動的百分比數,這一切都在一起可能是:
subsequence(//PatientInfo[1]/Patient, 1, round(count(//PatientInfo[1]/Patient) div 100 * 1))
如果這round(count(//PatientInfo[1]/Patient) div 100 * 1)
是1%
個圓,先算所有患者的節點,這個劃分爲100繁衍爲您的百分比。
請注意,我沒有SOAPUI PRO,所以我不能使用數據源來檢查它是否工作,但是我在SOAPUI的其他部分使用subsequence
XPath函數來實現類似於您的目標。我用的是後續常規例子來檢查這個XPath
該工程按預期:
import javax.xml.transform.TransformerFactory
import javax.xml.transform.Transformer
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
// xml sample to get Patient nodes
def xml = '<PatientInfo><Patient>1</Patient><Patient>2</Patient><Patient>3</Patient><Patient>4</Patient></PatientInfo>'
// xmlHolder to perform an XPath
def xmlHolder = new com.eviware.soapui.support.XmlHolder(xml)
// get the 50% of patients (in the sample 2 nodes)
// with XPath
def nodes = xmlHolder.getDomNodes("subsequence(//PatientInfo[1]/Patient, 1, round(count(//PatientInfo[1]/Patient) div 100 * 50))")
// print the nodes to check that only 2 first
// patient nodes where selected by the xpath
nodes.each{ n -> log.info printDocument(n)}
// this function is to print xml as string
// it's purpose it's only to log the info
def printDocument(node) {
TransformerFactory tf = TransformerFactory.newInstance()
Transformer transformer = tf.newTransformer()
StringWriter writer = new StringWriter()
transformer.transform(new DOMSource(node), new StreamResult(writer))
return writer.getBuffer().toString()
}
編輯基於OP評論:
關於你的新的要求,我認爲是存在的XPath沒有隨機函數,但是你可以與unordered(items)
函數試圖讓<patient>
無序的,但是這個功能的隨機性取決於實現,我不知道這是否正常工作在SOAPUI,表達可以是:
subsequence(unordered(//PatientInfo[1]/Patient), 1, round(count(//PatientInfo[1]/Patient) div 100 * 50))
另一種可能是使用groovy來填充您的數據源,將groovy組合成一個隨機數作爲subsequence
函數的起始點,並使用XPath
來獲取<patient>
節點。如果你有你的XML響應的測試步驟,你可以修改我前面的例子可以直接在XPath
適用於它,代碼可能是:
import javax.xml.transform.TransformerFactory
import javax.xml.transform.Transformer
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
import java.util.Random
// random number
def random = new Random();
// random as start point for subsequence
// use a number which doesn't exceed the number of patient nodes...
// you can use count(//PatientInfo[1]/Patient) to know the max number however
// you have to use a less number to start...
def start = random.nextInt(500)
// define the xpath to get 50% of patients starting
// to get patients from a random point in array
def xpath = 'subsequence(//PatientInfo[1]/Patient,' + start +', round(count(//PatientInfo[1]/Patient) div 100 * 50))'
// access test request response
def response = context.expand('${YourRequestTestName#response}')
// xmlHolder to perform an XPath
def xmlHolder = new com.eviware.soapui.support.XmlHolder(response)
// get nodes
def nodes = xmlHolder.getDomNodes(xpath)
// print the nodes to check that only 2 first
// patient nodes where selected by the xpath
nodes.each{ n -> log.info printDocument(n)}
// this function is to print xml as string
// it's purpose it's only to log the info
def printDocument(node) {
TransformerFactory tf = TransformerFactory.newInstance()
Transformer transformer = tf.newTransformer()
StringWriter writer = new StringWriter()
transformer.transform(new DOMSource(node), new StreamResult(writer))
return writer.getBuffer().toString()
}
希望這有助於
哇,完美的作品!非常感謝! – MattJ 2014-10-09 15:36:28
這對於能夠選擇第一個1%是完美的。謝謝!我希望隨機抽取1%的樣本,以便每次進行測試時都有可能對不同的患者進行評估。你會知道如何增加隨機性嗎? – MattJ 2014-10-09 15:54:08
@MattJoe關於你的新問題我認爲在XPath中沒有隨機函數,然而你可以試着用'無序(items)'函數來獲得無序的 ...但是這個函數的隨機性取決於實現, m不知道它是否在soapui中正常工作,表達式可能是:'subsequence(unordered(// PatientInfo [1]/Patient),1,round(count(// PatientInfo [1]/Patient)div 100 * 50) )'。 –
albciff
2014-10-09 21:42:21