0

The Open Source Static Analyser PMD is now supporting not only Apex but also rules on arbitrary XML metadata. Using flexible XPath expressions that verify the structure and attributes of XML.

I am thinking of writing a tool that helps people to write such rules more easily and need a way to get the structure/schema for a given metadata type. In the old MDAPI and the new Source format.

Is there an API where I can get the Schema, or a website with XML Schemas that get updated by Salesforce?

The only idea I can think of is:

  1. Apex-download the Metadata WSDL generated from the current org at https://serverinstance.salesforce.com/services/wsdl/metadata
  2. Parse its elements
1

I have always just downloaded the WSDL for the Metadata API and chopped the node with the type information out of it to get the schema. That takes care of MDAPI.

I’m not sure whether the new source format has different information, btw, or whether it’s just that the files are chopped up differently from MDAPI. Then there’s JSON instead of XML of course, but a systematic transformation from one to the other shouldn’t be hard to infer, I guess.

1

Made it work as planned in my question:

public with sharing class MetadataSchema {

    private Map<String, List<String>> schema = new Map<String, List<String>>();

    public MetadataSchema() {
        parse( metadataWsdl() );
    }

    private XmlStreamReader metadataWsdl() {
        HttpRequest request = new HttpRequest();
        request.setEndpoint(URL.getOrgDomainUrl().toExternalForm() + '/services/wsdl/metadata');
        request.setMethod('GET');
        request.setHeader('Cookie','sid=' + UserInfo.getSessionId());
        request.setHeader('Content-Type', 'application/xml');
        
        return new Http().send(request).getXmlStreamReader();
    }


    private void parse(XmlStreamReader reader) {
        String type;

        while(reader.hasNext()) {
            if(reader.getEventType() == XmlTag.START_ELEMENT) {
                if(reader.getLocalName() == 'complexType') {
                    type = reader.getAttributeValue(null, 'name');
                    schema.put(type, new List<Property>());
                }
                else if(reader.getLocalName() == 'element') {
                    property = reader.getAttributeValue(null, 'name');
                    schema.get(type).add(property);
                }
            }

            reader.next();
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.