'xmlstarlet is not working if name space is mentioned on the xml [duplicate]

I am running this command, and it works

xmlstarlet sel -t -v '/web-app/filter/filter-name/text()' ./sampleWeb.xml

Responds with

HeaderSecurityFilter
httpHeaderSecurity
httpHeaderSecurity
ContentSecurityPolicyFilter
ReferrerPolicyFilter

Content of sampleWeb.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <filter>
        <filter-name>HeaderSecurityFilter</filter-name>
        <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HeaderSecurityFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>httpHeaderSecurity</filter-name>
        <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
        <init-param>
            <param-name>antiClickJackingOption</param-name>
            <param-value>SAMEORIGIN</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>httpHeaderSecurity</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

    <filter>
        <filter-name>httpHeaderSecurity</filter-name>
        <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
        <async-supported>true</async-supported>
        <init-param>
            <param-name>hstsEnabled</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>hstsMaxAgeSeconds</param-name>
            <param-value>31556927</param-value>
        </init-param>
        <init-param>
            <param-name>hstsIncludeSubDomains</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter>
        <filter-name>ContentSecurityPolicyFilter</filter-name>
        <filter-class>YourPackagePath.ContentSecurityPolicyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ContentSecurityPolicyFilter</filter-name>
        <url-pattern>/*</url-pattern>
     </filter-mapping>
     <filter>
        <filter-name>ReferrerPolicyFilter</filter-name>
        <filter-class>my.package.ReferrerPolicyFilter</filter-class>
     </filter>
     <filter-mapping>
       <filter-name>ReferrerPolicyFilter</filter-name>
       <url-pattern>/*</url-pattern>
     </filter-mapping>

</web-app>

But If change the sampleWeb.xml to this (include xmlns, xsi and version)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                      https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
  version="6.0">
    <filter>
        <filter-name>HeaderSecurityFilter</filter-name>
        <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
    </filter>

the same command does not work

xmlstarlet sel -t -v '/web-app/filter/filter-name/text()' ./sampleWeb.xml

Edit

I read How to declare XPath namespaces in xmlstarlet? question, but this did not address it for tomcat web.xml. The question also does not mention -t and -v options. Hence its not a duplciate question. Please review it one more time before you decide to remove a perfectly correct and unique question. xmlstartet is a bit more complex to use as compared to other parsing. Eventually the -N and -u does not work for my problem.



Solution 1:[1]

You have to take the namespace into account because xmlns= defines a default namespace on this element and all of its children. Then pass it to xmlstarlet, like this:

xmlstarlet sel -N jak="https://jakarta.ee/xml/ns/jakartaee" -t -v '/jak:web-app/jak:filter/jak:filter-name/text()' sampleWeb.xml

Now the the output should be the same.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 zx485