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());
}
}