public void doXml()

in core/src/main/java/hudson/model/Api.java [92:200]


    public void doXml(StaplerRequest req, StaplerResponse rsp,
                      @QueryParameter String xpath,
                      @QueryParameter String wrapper,
                      @QueryParameter String tree,
                      @QueryParameter int depth) throws IOException, ServletException {
        setHeaders(rsp);

        String[] excludes = req.getParameterValues("exclude");

        if(xpath==null && excludes==null) {
            // serve the whole thing
            rsp.serveExposedBean(req,bean,Flavor.XML);
            return;
        }

        StringWriter sw = new StringWriter();

        // first write to String
        Model p = MODEL_BUILDER.get(bean.getClass());
        TreePruner pruner = (tree!=null) ? new NamedPathPruner(tree) : new ByDepth(1 - depth);
        p.writeTo(bean,pruner,Flavor.XML.createDataWriter(bean,sw));

        // apply XPath
        FilteredFunctionContext functionContext = new FilteredFunctionContext();
        Object result;
        try {
            Document dom = new SAXReader().read(new StringReader(sw.toString()));
            // apply exclusions
            if (excludes!=null) {
                for (String exclude : excludes) {
                    XPath xExclude = dom.createXPath(exclude);
                    xExclude.setFunctionContext(functionContext);
                    List<org.dom4j.Node> list = (List<org.dom4j.Node>)xExclude.selectNodes(dom);
                    for (org.dom4j.Node n : list) {
                        Element parent = n.getParent();
                        if(parent!=null)
                            parent.remove(n);
                    }
                }
            }
            
            if(xpath==null) {
            	result = dom;
            } else {
                XPath comp = dom.createXPath(xpath);
                comp.setFunctionContext(functionContext);
                List list = comp.selectNodes(dom);

                if (wrapper!=null) {
                    // check if the wrapper is a valid entity name
                    // First position:  letter or underscore
                    // Other positions: \w (letter, number, underscore), dash or dot
                    String validNameRE = "^[a-zA-Z_][\\w-\\.]*$";

                    if(!wrapper.matches(validNameRE)) {
                        rsp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                        rsp.getWriter().print(Messages.Api_WrapperParamInvalid());
                        return;
                    }

                    Element root = DocumentFactory.getInstance().createElement(wrapper);
                    for (Object o : list) {
                        if (o instanceof String) {
                            root.addText(o.toString());
                        } else {
                            root.add(((org.dom4j.Node)o).detach());
                        }
                    }
                    result = root;
                } else if (list.isEmpty()) {
                    rsp.setStatus(HttpServletResponse.SC_NOT_FOUND);
                    rsp.getWriter().print(Messages.Api_NoXPathMatch(xpath));
                    return;
                } else if (list.size() > 1) {
                    rsp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    rsp.getWriter().print(Messages.Api_MultipleMatch(xpath,list.size()));
                    return;
                } else {
                    result = list.get(0);
                }
            }

        } catch (DocumentException e) {
            LOGGER.log(Level.FINER, "Failed to do XPath/wrapper handling. XML is as follows:"+sw, e);
            throw new IOException("Failed to do XPath/wrapper handling. Turn on FINER logging to view XML.",e);
        }


        if (isSimpleOutput(result) && !permit(req)) {
            // simple output prohibited
            rsp.sendError(HttpURLConnection.HTTP_FORBIDDEN, "primitive XPath result sets forbidden; implement jenkins.security.SecureRequester");
            return;
        }

        // switch to gzipped output
        try (OutputStream o = rsp.getCompressedOutputStream(req)) {
            if (isSimpleOutput(result)) {
                // simple output allowed
                rsp.setContentType("text/plain;charset=UTF-8");
                String text = result instanceof CharacterData ? ((CharacterData) result).getText() : result.toString();
                o.write(text.getBytes(StandardCharsets.UTF_8));
                return;
            }

            // otherwise XML
            rsp.setContentType("application/xml;charset=UTF-8");
            new XMLWriter(o).write(result);
        }
    }