apex xml

XML 支持

Apex 提供了实用程序类,用于创建和解析 使用流和 DOM 的 XML 内容。

本节包含有关 XML 支持的详细信息。

  • 使用 Streams
    读取和写入 XML Apex 提供了用于使用流读取和写入 XML 内容的类。
  • 使用 DOM
    读取和写入 XML Apex 提供了使您能够使用 DOM(文档对象模型)处理 XML 内容的类。

使用流读取和写入 XML

Apex 提供了用于使用流读取和写入 XML 内容的类。

使用 XMLStreamReader 类可以读取 XML 内容和 XMLStreamWriter 类使您能够编写 XML 内容。

  • 使用流
    读取 XML XMLStreamReader 类方法支持对 XML 数据的正向只读访问。
  • 使用流
    编写 XML XmlStreamWriter 类方法允许写入 XML 数据。

使用流读取 XML

XMLStreamReader 类方法支持对 XML 的正向只读访问 数据。这些方法与 HTTP 标注结合使用,以解析 XML 数据或跳过 不需要的事件。您可以分析最

50节点深度。下面的示例演示如何 实例化新的 XmlStreamReader 对象:

String xmlString = '<books><book>My Book</book><book>Your Book</book></books>';
XmlStreamReader xsr = new XmlStreamReader(xmlString);

这些方法适用于以下 XML 事件:

  • 为特定元素指定属性事件。例如 该元素具有属性:。<book>title<book title=”Salesforce.com for Dummies”>
  • start 元素事件是元素的开始标记,例如 。<book>
  • 结束元素事件是元素的结束标记,例如 。</book>
  • 开始文档事件是文档的开始标记。
  • 结束文档事件是文档的结束标记。
  • 实体引用是代码中的实体引用,例如 。!ENTITY title = “My Book Title”
  • 字符事件是文本字符
  • 注释事件是 XML 文件中的注释。

使用 and 方法循环访问 XML 数据。使用 方法(如 the 方法)访问 XML 中的数据。nexthasNextgetgetNamespace

循环访问 XML 数据时,请始终在调用之前检查流数据是否可用,以避免尝试读取 XML 数据。hasNextnext

XmlStreamReader 示例

下面的示例处理一个 XML 字符串。

public class XmlStreamReaderDemo {

    // Create a class Book for processing
    public class Book {
        String name;
        String author;
    }

    public Book[] parseBooks(XmlStreamReader reader) {
        Book[] books = new Book[0];
        boolean isSafeToGetNextXmlElement = true;
        while(isSafeToGetNextXmlElement) {
            // Start at the beginning of the book and make sure that it is a book
            if (reader.getEventType() == XmlTag.START_ELEMENT) {
                if ('Book' == reader.getLocalName()) {
                    // Pass the book to the parseBook method (below) 
                    Book book = parseBook(reader);
                    books.add(book);
                }
            }
            // Always use hasNext() before calling next() to confirm 
            // that we have not reached the end of the stream
            if (reader.hasNext()) {
                reader.next();
            } else {
                isSafeToGetNextXmlElement = false;
                break;
            }
        }
        return books;
    }

    // Parse through the XML, determine the author and the characters
    Book parseBook(XmlStreamReader reader) {
        Book book = new Book();
        book.author = reader.getAttributeValue(null, 'author');
        boolean isSafeToGetNextXmlElement = true;
        while(isSafeToGetNextXmlElement) {
            if (reader.getEventType() == XmlTag.END_ELEMENT) {
                break;
            } else if (reader.getEventType() == XmlTag.CHARACTERS) {
                book.name = reader.getText();
            }
            // Always use hasNext() before calling next() to confirm 
            // that we have not reached the end of the stream
            if (reader.hasNext()) {
                reader.next();
            } else {
                isSafeToGetNextXmlElement = false;
                break;
            }
        }
        return book;
    }
}
@isTest
private class XmlStreamReaderDemoTest {
    // Test that the XML string contains specific values
    static testMethod void testBookParser() {

        XmlStreamReaderDemo demo = new XmlStreamReaderDemo();

        String str = '<books><book author="Chatty">Alpha beta</book>' +
            '<book author="Sassy">Baz</book></books>';

        XmlStreamReader reader = new XmlStreamReader(str);
        XmlStreamReaderDemo.Book[] books = demo.parseBooks(reader);

        System.debug(books.size());

        for (XmlStreamReaderDemo.Book book : books) {
            System.debug(book);
        }
    }
}

使用流编写 XML

XmlStreamWriter 类方法允许编写 XML 数据。这些方法与 HTTP 标注结合使用以构造 要在标注请求中发送到外部服务的 XML 文档。 下面的示例演示如何实例化新的 XmlStreamReader 对象:

String xmlString = '<books><book>My Book</book><book>Your Book</book></books>';
XmlStreamReader xsr = new XmlStreamReader(xmlString);

XML 编写器方法 例

下面的示例编写一个 XML 文档 并测试其有效性。

此 Hello World 示例需要自定义对象。您可以 您可以自行创建这些代码,或将对象和 Apex 代码下载为非托管包 来自 Salesforce AppExchange。要获取组织中的示例资产,请安装 Apex 教程包。此套餐 还包含装运发票示例的示例代码和对象。

public class XmlWriterDemo {

     public String getXml() {
          XmlStreamWriter w = new XmlStreamWriter();
          w.writeStartDocument(null, '1.0');
          w.writeProcessingInstruction('target', 'data');
          w.writeStartElement('m', 'Library', 'http://www.book.com');
          w.writeNamespace('m', 'http://www.book.com');
          w.writeComment('Book starts here');
          w.setDefaultNamespace('http://www.defns.com');
          w.writeCData('<Cdata> I like CData </Cdata>');
          w.writeStartElement(null, 'book', null);
          w.writedefaultNamespace('http://www.defns.com');
          w.writeAttribute(null, null, 'author', 'Manoj');
          w.writeCharacters('This is my book');
          w.writeEndElement(); //end book
          w.writeEmptyElement(null, 'ISBN', null);
          w.writeEndElement(); //end library
          w.writeEndDocument();
          String xmlOutput = w.getXmlString();
          w.close();
          return xmlOutput;
        }
}
@isTest
private class XmlWriterDemoTest {
    static TestMethod void basicTest() {
        XmlWriterDemo demo = new XmlWriterDemo();
        String result = demo.getXml();
        String expected = '<?xml version="1.0"?><?target data?>' +
            '<m:Library xmlns:m="http://www.book.com">' + 
            '<!--Book starts here-->' +
            '<![CDATA[<Cdata> I like CData </Cdata>]]>' +
'<book xmlns="http://www.defns.com" author="Manoj">This is my book</book><ISBN/></m:Library>';
        
        System.assert(result == expected);
    }
}

使用 DOM 读取和写入 XML

Apex 提供了使您能够使用 DOM 处理 XML 内容的类 (文档对象模型)。

DOM 类可帮助您解析或生成 XML 内容。您可以使用这些类来工作 替换为任何 XML 内容。一个常见的应用是使用类来生成正文 由 HttpRequest 创建的请求或解析 HttpResponse 访问的响应。The DOM 将 XML 文档表示为节点层次结构。某些节点可能是分支节点 并且有子节点,而其他节点是没有子节点的叶节点。您可以 分析嵌套的 XML 内容,该内容最多50节点 深。

DOM 类包含在命名空间中。Dom

使用 Document 类处理 XML 文档正文中的内容。

使用 XmlNode 类处理 XML 中的节点 公文。

使用 Document 类类处理 XML 内容。一个常见的应用是使用它 为 HttpRequest 创建请求的正文,或分析 HttpResponse 访问的响应。

XML 命名空间

XML 命名空间是由 URI 引用标识的名称集合,用于 XML 文档,用于唯一标识元素类型和属性名称。XML 中的名称 命名空间可能显示为限定名称,其中包含一个冒号,分隔 名称转换为命名空间前缀和本地部分。前缀,映射到 URI 引用,选择命名空间。通用管理 URI 的组合 命名空间和文档自己的命名空间生成通用的标识符 独特。

以下 XML 元素的命名空间和前缀为 。http://my.name.spacemyprefix

<sampleElement xmlns:myprefix="http://my.name.space" />

在下面的示例中,XML 元素具有两个属性:

  • 第一个属性的键为 ; 值为 。dimension2
  • 第二个属性的键命名空间为 http://ns1;这 value 命名空间为 http://ns2;关键是;值为 。exampletest
<square dimension="2" ns1:example="ns2:test" xmlns:ns1="http://ns1" xmlns:ns2="http://ns2" />

公文例

对于下面的示例,假定传递到方法中的参数返回此 XML 响应:urlparseResponseDom

<address>
    <name>Kirk Stevens</name>
    <street1>808 State St</street1>
    <street2>Apt. 2</street2>
    <city>Palookaville</city>
    <state>PA</state>
    <country>USA</country>
</address>

下面的示例演示如何使用 DOM 类来分析 XML 响应 在请求正文中返回:GET

public class DomDocument {
 
    // Pass in the URL for the request
    // For the purposes of this sample,assume that the URL
    // returns the XML shown above in the response body
    public void parseResponseDom(String url){
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        // url that returns the XML in the response body
        req.setEndpoint(url);
        req.setMethod('GET');
        HttpResponse res = h.send(req);
        Dom.Document doc = res.getBodyDocument();
        
        //Retrieve the root element for this document.
        Dom.XMLNode address = doc.getRootElement();
        
        String name = address.getChildElement('name', null).getText();
        String state = address.getChildElement('state', null).getText();
        // print out specific elements
        System.debug('Name: ' + name);
        System.debug('State: ' + state);
        
        // Alternatively, loop through the child elements.
        // This prints out all the elements of the address
        for(Dom.XMLNode child : address.getChildElements()) {
           System.debug(child.getText());
        }
    }
}

使用 XML 节点

使用该类处理 XML 文档。DOM 将 XML 文档表示为节点的层次结构。一些 节点可以是分支节点并具有子节点,而其他节点是没有子节点的叶节点 孩子。XmlNode

Apex 中有不同类型的 DOM 节点可用。 是这些不同类型的枚举。 这些值为:XmlNodeType

  • 评论
  • 元素
  • 发短信

区分 XML 文档中的元素和节点非常重要。这 下面是一个简单的 XML 示例:

<name>
    <firstName>Suvain</firstName>
    <lastName>Singh</lastName>
</name>

此示例包含三个 XML 元素:、 和 。它包含五个节点:三个节点 、 和 元素 节点,以及两个文本节点 – 和 .请注意,元素中的文本 节点被视为单独的文本节点。namefirstNamelastNamenamefirstNamelastNameSuvainSingh

有关所有枚举共享的方法的详细信息,请参阅枚举方法。

XmlNode的例

此示例演示如何使用方法 和命名空间来创建 XML 请求。XmlNode

public class DomNamespaceSample
{
    public void sendRequest(String endpoint)
    {
        // Create the request envelope
        DOM.Document doc = new DOM.Document();
        
        String soapNS = 'http://schemas.xmlsoap.org/soap/envelope/';
        String xsi = 'http://www.w3.org/2001/XMLSchema-instance';
        String serviceNS = 'http://www.myservice.com/services/MyService/';
        
        dom.XmlNode envelope
            = doc.createRootElement('Envelope', soapNS, 'soapenv');
        envelope.setNamespace('xsi', xsi);
        envelope.setAttributeNS('schemaLocation', soapNS, xsi, null);
        
        dom.XmlNode body
            = envelope.addChildElement('Body', soapNS, null);
        
        body.addChildElement('echo', serviceNS, 'req').
           addChildElement('category', serviceNS, null).
           addTextNode('classifieds');
        
        System.debug(doc.toXmlString());
        
        // Send the request
        HttpRequest req = new HttpRequest();
        req.setMethod('POST');
        req.setEndpoint(endpoint);
        req.setHeader('Content-Type', 'text/xml');
        
        req.setBodyDocument(doc);
        
        Http http = new Http();
        HttpResponse res = http.send(req);
        
        System.assertEquals(200, res.getStatusCode());
        
        dom.Document resDoc = res.getBodyDocument();
        
        envelope = resDoc.getRootElement();
        
        String wsa = 'http://schemas.xmlsoap.org/ws/2004/08/addressing';
        
        dom.XmlNode header = envelope.getChildElement('Header', soapNS);
        System.assert(header != null);
        
        String messageId
            = header.getChildElement('MessageID', wsa).getText();
        
        System.debug(messageId);
        System.debug(resDoc.toXmlString());
        System.debug(resDoc);
        System.debug(header);
        
        System.assertEquals(
         'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous',
         header.getChildElement(
           'ReplyTo', wsa).getChildElement('Address', wsa).getText());
        
        
        System.assertEquals(
          envelope.getChildElement('Body', soapNS).
              getChildElement('echo', serviceNS).
              getChildElement('something', 'http://something.else').
              getChildElement(
                'whatever', serviceNS).getAttribute('bb', null),
                'cc');
        
        System.assertEquals('classifieds',
          envelope.getChildElement('Body', soapNS).
              getChildElement('echo', serviceNS).
              getChildElement('category', serviceNS).getText());
    }
}