📄 index.html
字号:
<li>Supply name as an <tt>XMLCh</tt> array</li>
<li><tt>XMLCh</tt> array must be deleted</li>
</ul>
</li>
<li>Wrap <tt>getAttribute</tt> method in a help function:</li>
</ul>
</font>
<hr><h2><font color="#009999">29.2 Parsing XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<blockquote>
<pre>string get_attribute(DOMElement* element, string name)
{
XMLCh* xname = new XMLCh[name.length() + 1];
XMLString::transcode(name.c_str(),
xname, name.length());
XMLCh* xvalue = element->getAttribute(xname);
delete xname;
return XMLCh_to_string(xvalue);
}</pre>
</blockquote>
<li>E.g., get the <tt>currency</tt> attribute</li>
<blockquote><tt>
string attribute_value = get_attribute(<br>
price_element, "currency");
</tt></blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">29.2 Parsing XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>Use <tt>DOMNamedNodeMap</tt> to iterate over attributes</li>
<li>Returned by <tt>getAttributes</tt>:
<blockquote><tt>
DOMNamedNodeMap* attributes = price_element->getAttributes();
</tt></blockquote>
</li>
<li>Use <tt>item</tt> method to get a particular attribute:
<blockquote><tt>
int i = . . .;<br>
<font color="#0000cc">
// # between 0 and attributes->getLength() - 1</font><br>
DOMNode* attribute_node = attributes->item(i);<br>
XMLCh* attribute_name = attribute_node->getNodeName();<br>
<font color="#0000cc">// For example, "currency"</font><br>
XMLCh* attribute_value = attribute_node.getNodeValue();<br>
<font color="#0000cc">// For example, "USD"</font>
</tt></blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">29.2 Parsing XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>Text node stored in <tt>DOMText</tt></li>
<li>If no mixed content, should be only child</li>
<li>Use <tt>getFirstChild</tt> to retrieve</li>
<li>Use <tt>getData</tt> to read the text</li>
<blockquote><tt>
DOMNode* price_element = . . .;<br>
DOMText* price_data = <nobr>dynamic_cast<DOMText*></nobr>(<br>
price_element->getFirstChild());<br>
string price_string = XMLCh_to_string(price_data->getData());<br>
<font color="#0000cc">// For example, "24.95"</font><br>
double price = string_to_double(price_string);<br>
<font color="#0000cc">// For example, 24.95</font>
</tt></blockquote>
</ul>
</font>
<hr><h2><font color="#009999">29.2 Parsing XML Documents - Parser example
</font></h2>
<font size="+1">
<ul>
<li>Create a helper function for each XML element</li>
<li><tt>description</tt>, <tt>price</tt>, and <tt>quantity</tt> simple,
so parsed inline</li>
<li><tt>main</tt> calls <tt>XMLPlatformUtils::Initialize</tt>; necessary
to use Xerces</li>
<li>Program:
<ul>
<li>Parses
<a target='bigc' href='Code/parser/items.xml'><tt>items.xml</tt></a>,
description of a list of product items</li>
<li>Produces a vector of <tt>Item</tt> objects</li>
</ul>
</li>
<li>Uses <a target='bigc' href='Code/parser/item.h'><tt>item.h</tt></a>,
<a target='bigc' href='Code/parser/item.cpp'><tt>item.cpp</tt></a>,
<a target='bigc' href='Code/parser/product.h'><tt>product.h</tt></a>, and
<a target='bigc' href='Code/parser/product.cpp'><tt>product.cpp</tt></a>
from (chptr 13)</li>
</ul>
</font>
<hr><h2><font color="#009999">29.2 Parsing XML Documents (parser.cpp)
</font></h2>
<font size="+1">
<script><!--
iframeWrapCode( "parser/parser.cpp", "95%", "80%" )
//--></script>
</font>
<hr><h2><font color="#009999">Productivity Hint 29.1</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">
<p><font color="#009999">Helper Functions in an XML Parser</font></p>
<ul>
<li>Given an XML document of a particular structure</li>
<li>For each element:
<ul>
<li>Assign a (new or existing) class or vector (for sequences of the
same type)</li>
<li>Provide a helper function of this form:</li>
</ul>
</li>
</ul>
</font>
<hr><h2><font color="#009999">Productivity Hint 29.1 (cont.)</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">
<blockquote>
<pre><i>ClassForElement</i> get<i>ElementName</i>(DOMNode* e)
{
DOMNodeList* children = e->getChildNodes();
for (int i = 0; i < children->getLength(); i++)
{
DOMNode* child_node = children->item(i);
DOMElement* child_element
= dynamic_cast<DOMElement*>(child_node);
if (child_element != NULL)
{
Get value of child element
}
}
<i>Use the child element values to construct and
return a ClassForElement object</i>
}</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">Productivity Hint 29.1 (cont.)</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">
<ul>
<li>If a child element doesn't contain text, call its
<tt>get<i>ChildElementName</i></tt> function</li>
<li>If it does, then read the element data:
<blockquote>
<pre>DOMText* text_node = dynamic_cast<DOMText*>(
child_element->getFirstChild());
string data = XMLCh_to_string(text_node->getData());</pre>
</blockquote>
</li>
<li>Convert strings to numbers, as necessary</li>
<li>Implement functions bottom-up</li>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents</font></h2>
<font size="+1">
<ul>
<li>Avoid simple print statements - easy to introduce an error</li>
<li>Build a <tt>DOMDocument</tt> object</li>
<li>Still use <tt>DOMImplementation</tt> object to create parser:
<blockquote><tt>
DOMImplementation* implementation<br>
= DOMImplementation::getImplementation();<br>
DOMDocument* doc = implementation->createDocument();<br>
doc->setStandalone(true);<br>
<font color="#0000cc">// An empty document</font>
</tt></blockquote>
</li>
<li>"standalone" flag indicates lack of document type definition
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>Use <tt>createElement</tt> and <tt>createTextNode</tt> methods
of <tt>DOMDocument</tt></li>
<li>Inputs are an <tt>XMLCh</tt> array</li>
<li>So, wrap above methods, to take <tt>string</tt>s</li>
<li>Wrapper for <tt>DOMDocument::createElement</tt>:
<blockquote>
<pre>DOMElement* create_element(DOMDocument* doc, string name)
{
XMLCh* xname = new XMLCh[name.length() + 1];
XMLString::transcode(name.c_str(), xname, name.length());
DOMElement* r = doc->createElement(xname);
delete xname;
return r;
}</pre>
</blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>To insert text node:
<ul>
<li>Convert text to <tt>XMLCh</tt> array</li>
<li>Wrap in a text node</li>
<li>Create an element node</li>
<li>Set text node as child</li>
</ul>
</li>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<blockquote>
<pre>DOMElement* create_text_element(DOMDocument* doc,
string name, string text)
{
XMLCh* xtext = new XMLCh[text.length() + 1];
XMLString::transcode(text.c_str(), xtext, text.length());
DOMText* textNode = doc->createTextNode(xtext);
delete xtext;
DOMElement* r = create_element(doc, name);
r->appendChild(textNode);
return r;
}</pre>
</blockquote>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>Build DOM tree to save to an XML document, for persistence or
transmission</li>
<li>Set attributes w/the <tt>setAttribute</tt> method</li>
<li>E.g.,
<blockquote><tt>
XMLCh xname = . . .;<br>
XMLCh xvalue = . . .;<br>
price_element->setAttribute(xname, xvalue);
</tt></blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>Start with root, then add children</li>
<li>Consider the simple tree:</li>
<script><!--
image( "fig08.png" )
//--></script>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>First, create elements:
<blockquote>
<pre>DOMElement* itemElement = create_element(doc, "item");
DOMElement* product_element = create_element(doc, "product");
DOMElement* description_element = create_text_element(doc,
"description", "Ink Jet Refill Kit");
DOMElement* price_element = create_text_element(doc,
"price", "29.95");
DOMElement* quantity_element
= create_text_element(doc, "quantity", "8");</pre>
</blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>Then add elements to the document:
<blockquote>
<pre>doc->appendChild(item_element);
item_element->appendChild(product_element);
item_element->appendChild(quantity_element);
product_element->appendChild(description_element);
product_element->appendChild(price_element);</pre>
</blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>Organize these steps into helper functions</li>
<li>Sample program (later) uses:
<blockquote>
<pre>DOMElement* create_product(DOMDocument* doc, const Product& p)
DOMElement* create_item(DOMDocument* doc, const Item& anItem)
DOMElement* create_item_list(DOMDocument* doc,
const vector<Item>& items)</pre>
</blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>Obtain <tt>DOMWriter</tt> object from the <tt>DOMImplementation</tt>
object:
<blockquote><tt>
DOMWriter* writer = implementation->createDOMWriter();<br>
writer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
</tt></blockquote>
</li>
<li>"Pretty print" aligns elements</li>
<li>Default is w/out whitespace</li>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (cont.)</font></h2>
<font size="+1">
<ul>
<li>A "format target" is needed</li>
<li>To print to <tt>stdout</tt>:
<blockquote><tt>
XMLFormatTarget* out = new StdOutFormatTarget();<br>
writer->writeNode(out, *doc);
</tt></blockquote>
</li>
<li>To write to a local file:
<blockquote><tt>
XMLCh* filename = . . .;
XMLFormatTarget* out = new LocalFileFormatTarget(filename);
writer->writeNode(out, *doc);
</tt></blockquote>
</li>
<li><tt>writeNode</tt> takes a <tt>DOMDocument</tt>, not a ptr</li>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents - Sample</font></h2>
<font size="+1">
<ul>
<li>Sample program uses
<a target='bigc' href='Code/builder/item.h'><tt>item.h</tt></a>,
<a target='bigc' href='Code/builder/item.cpp'><tt>item.cpp</tt></a>,
<a target='bigc' href='Code/builder/product.h'><tt>product.h</tt></a>, and
<a target='bigc' href='Code/builder/product.cpp'><tt>product.cpp</tt></a>
from (chptr 13)</li>
<li>Added <tt>get_product</tt> and <tt>get_quantity</tt> to <tt>Item</tt></li>
</ul>
</font>
<hr><h2><font color="#009999">29.3 Creating XML Documents (<tt>builder.cpp</tt>)
</font></h2>
<font size="+1">
<script><!--
iframeWrapCode( "builder/builder.cpp", "90%", "80%" )
//--></script>
</font>
<hr><h2><font color="#009999">29.4 Document Type Definitions</font></h2>
<font size="+1">
<ul>
<li>DTD - set of rules for correctly formed documents of a particular
type</li>
<li>E.g., consider the <tt>items</tt> document:
<ul>
<li><tt>items</tt> denotes a sequence of <tt>item</tt> elements</li>
<li><tt>item</tt> contains a <tt>product</tt> and a <tt>quantity</tt></li>
<li><tt>product</tt> contains a <tt>description</tt> and a
<tt>price</tt></li>
<li>Each of these elements contains descriptive text</li>
</ul>
</li>
<li>DTD formalizes this description</li>
</ul>
</font>
<hr><h2><font color="#009999">29.4 Document Type Definitions (cont.)</font></h2>
<font size="+1">
<ul>
<li>Sequence of rules that describe:
<ul>
<li>Legal attributes for each element type</li>
<li>Legal child elements for each element type</li>
</ul>
</li>
<li>Legal child elements are described by an ELEMENT rule:
<blockquote><tt>
<!ELEMENT items (item*)>
</tt></blockquote>
<tt>items</tt> must contain 0 or more <tt>item</tt> elements
</li>
<li>Delimited by <tt><!. . .></tt></li>
<li>Contains element whose children are to be constrained</li>
<li>Followed by description of children</li>
</ul>
</font>
<hr><h2><font color="#009999">29.4 Document Type Definitions (cont.)</font></h2>
<font size="+1">
<ul>
<li>Definition of <tt>item</tt> node:
<blockquote><tt>
<!ELEMENT item (product, quantity)>
</tt></blockquote>
</li>
<li>Children of <tt>item</tt> must be a <tt>product</tt> node, followed
by a <tt>quantity</tt> node</li>
<li><tt>product</tt> is similar:
<blockquote><tt>
<!ELEMENT product (description, price)>
</tt></blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">29.4 Document Type Definitions (cont.)</font></h2>
<font size="+1">
<ul>
<li>The three remaining node types:
<blockquote><tt>
<!ELEMENT quantity (#PCDATA)><br>
<!ELEMENT description (#PCDATA)><br>
<!ELEMENT price (#PCDATA)>
</tt></blockquote>
</li>
<li><tt>#PCDATA</tt> refers to text; <i>parsable character data</i></li>
</ul>
</font>
<hr><h2><font color="#009999">29.4 Document Type Definitions (cont.)</font></h2>
<font size="+1">
<ul>
<li>Certain characters need to be encoded:
<br><br>
<table border='1'>
<tr bgcolor='#00ffff'>
<th>Character</th>
<th>Encoding</th>
<th>Name</th>
</tr>
<tr>
<td align='center'><</td>
<td align='center'>&lt;</td>
<td align='center'>Less than (left angle bracket)</td>
</tr>
<tr>
<td align='center'>></td>
<td align='center'>&gt;</td>
<td align='center'>Greater than (right angle bracket)</td>
</tr>
<tr>
<td align='center'>&</td>
<td align='center'>&amp;</td>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -