xmlxmllint

Need to read data from xml using xmllint


I would like to read "url-pattern" from below.

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>APP Services</display-name>
    <servlet-mapping>
        <servlet-name>LoginLogoutMapping</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
    <security-constraint>
      <web-resource-collection>
      <web-resource-name >APP restricted URLs</web-resource-name>
      <url-pattern>/services.jsp</url-pattern>
      <url-pattern>/Debug.jsp</url-pattern>
      <url-pattern>/encode.jsp</url-pattern>
    </web-resource-collection>
    <auth-constraint/>
    </security-constraint>
</web-app>

Tried some commands. Doesn't help/

sh-4.4$ xmllint --xpath '//web-app/security-constraint/web-resource-collection/web-resource-name/' /optconf/web.xml XPath error : Invalid expression XPath evaluation failure sh-4.4$ sh-4.4$


Solution

  • The error appears to be caused by the xpath ending in a /.

    You also don’t have url-pattern in the path.

    Thirdly, your xml has a default namespace which you’ll need to account for. (This answer should help.)

    Here's an example using the local-name() option from the answer linked above:

    ==> xmllint --xpath '/*[local-name()="web-app"]/*[local-name()="security-constraint"]/*[local-name()="web-resource-collection"]/*[local-name()="url-pattern"]' input.xml 
    <url-pattern>/services.jsp</url-pattern><url-pattern>/Debug.jsp</url-pattern><url-pattern>/encode.jsp</url-pattern>
    

    This will select the three url-pattern elements that are descendants of security constraint. (This xpath can probably be simplified if some requirements on which url-pattern elements need to be selected.)

    Also, newer versions of xmlstarlet (I used 1.6.1) allow _ as a namespace prefix that will match nodes in any namespace. It also gives you greater control over the output.

    Example...

    ==> xmlstarlet sel -t -m '/_:web-app/_:security-constraint/_:web-resource-collection' -v '_:url-pattern' input.xml 
    /services.jsp
    /Debug.jsp
    /encode.jsp