Spring int-xml:xpath-expression erros with node fu

2019-03-02 07:44发布

I used XMLSpy to write the following XPath to determine the longest string length and it works in XMLSpy:

string-length(//exception:ElementMessageAbcException/@exceptionMsg[not(string-length(.) < //exception:ElementMessageAbcException/@exceptionMsg/string-length(.))] )

But when I put the same string into a xpath-expression in spring integration it errors:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xpathMaxLengthExceptionMsg': Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public static org.springframework.xml.xpath.XPathExpression org.springframework.xml.xpath.XPathExpressionFactory.createXPathExpression(java.lang.String,java.util.Map) throws java.lang.IllegalStateException,org.springframework.xml.xpath.XPathParseException] threw exception; nested exception is org.springframework.xml.xpath.XPathParseException: Could not compile [//exception:MarkitMessageAciException/@exceptionMsg[not(string-length() < //exception:MarkitMessageAciException/@exceptionMsg/string-length())]] to a XPathExpression: null; nested exception is javax.xml.xpath.XPathExpressionException Caused by: javax.xml.transform.TransformerException: Unknown nodetype: string-length

<int-xml:xpath-expression id="xpathMaxLengthExceptionMsg" expression="//exception:ElementMessageAciException/@exceptionMsg[not(string-length(.) &lt; //exception:ElementMessageAciException/@exceptionMsg/string-length(.))]">
    <map>
        <entry key="pricing" value="http://www.example.net/imdwrd/schemas/Element-pricing-aci" />
        <entry key="security" value="http://www.example.net/imdwrd/schemas/Element-security-aci" />
        <entry key="tns" value="http://www.example.net/imdwrd/schemas/Element-message-aci" />
        <entry key="internalClassification" value="http://www.example.net/imdwrd/schemas/Element-internal-classification" />
        <entry key="organization" value="http://www.example.net/imdwrd/schemas/Element-organization-aci" />
        <entry key="exception" value="http://www.example.net/imdwrd/schemas/Element-message-aci-exception"/>
        <entry key="xsi" value="http://www.w3.org/2001/XMLSchema-instance" />
    </map>
</int-xml:xpath-expression>

Sample XML:

<?xml version="1.0" encoding="UTF-8"?>
<confirm:ElementMessageAbcConfirm
  confirmTs="2014-10-14T11:43:36.191-05:00"
  correlationId="ORG-1008891250014" numberAccepted="0"
  numberRejected="1" status="exception"
  xmlns:ack="http://www.example.net/imdwrd/schemas/Element-message-Abc-ack"
  xmlns:confirm="http://www.example.net/imdwrd/schemas/Element-message-Abc-confirm"
  xmlns:event="http://www.example.net/imdwrd/schemas/data-source-event"
  xmlns:exception="http://www.example.net/imdwrd/schemas/Element-message-Abc-exception"
  xmlns:internalClassification="http://www.example.net/imdwrd/schemas/Element-internal-classification"
  xmlns:ns9="http://www.example.net/imdwrd/schemas/Element-message-Abc"
  xmlns:organization="http://www.example.net/imdwrd/schemas/Element-organization-Abc"
  xmlns:pricing="http://www.example.net/imdwrd/schemas/Element-pricing-Abc" xmlns:security="http://www.example.net/imdwrd/schemas/Element-security-Abc">
  <exception:ElementMessageAbcException exceptionCode="1000"
    exceptionMsg="[property]=Organization [message]=Organization information has not changed.  Update request has been cancelled."
    exceptionType="informational" id="385059141722030" type="organization"/>
 <exception:ElementMessageAbcException exceptionCode="1000"
    exceptionMsg="[property]=Organization [message]=Organizatiosn information has not changed.  Update request has been cancelled. longer"
    exceptionType="informational" id="385059141722030" type="organization"/>    
</confirm:ElementMessageAbcConfirm>

1条回答
手持菜刀,她持情操
2楼-- · 2019-03-02 08:32

I don't know how XML Spy does work, but I see that this:

/@exceptionMsg/string-length(.)

is a wrong syntax. string-length() is really an xPath function, but it isn't a node of your XML.

It isn't clear yet what is your goal, but I hope it should help a bit to go right way.

UPDATE

Well, I've figured out what's going on.

You use XPath 2 (How do I select an XML node with the longest child #text node value with XPath?), but Java doesn't have that ability by default.

So you should use some other library. Saxon is the best one on the matter.

However you should do this:

-Djavax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom=net.sf.saxon.xpath.XPathFactoryImpl

Or specify that System property programmatically.

查看更多
登录 后发表回答