The QDomNode 类是 DOM (文档对象模型) 树中所有节点的基类。 更多...
头: | #include <QDomNode> |
qmake: | QT += xml |
继承者: | QDomAttr , QDomCharacterData , QDomDocument , QDomDocumentFragment , QDomDocumentType , QDomElement , QDomEntity , QDomEntityReference , QDomNotation ,和 QDomProcessingInstruction |
注意: 此类的所有函数 可重入 .
enum | EncodingPolicy { EncodingFromDocument, EncodingFromTextStream } |
enum | NodeType { ElementNode, AttributeNode, TextNode, CDATASectionNode, ..., CharacterDataNode } |
QDomNode () | |
QDomNode (const QDomNode & n ) | |
~QDomNode () | |
QDomNode | appendChild (const QDomNode & newChild ) |
QDomNamedNodeMap | 属性 () const |
QDomNodeList | childNodes () const |
void | clear () |
QDomNode | cloneNode (bool deep = true) const |
int | columnNumber () const |
QDomNode | firstChild () const |
QDomElement | firstChildElement (const QString & tagName = QString()) const |
bool | hasAttributes () const |
bool | hasChildNodes () const |
QDomNode | insertAfter (const QDomNode & newChild , const QDomNode & refChild ) |
QDomNode | insertBefore (const QDomNode & newChild , const QDomNode & refChild ) |
bool | isAttr () const |
bool | isCDATASection () const |
bool | isCharacterData () const |
bool | isComment () const |
bool | isDocument () const |
bool | isDocumentFragment () const |
bool | isDocumentType () const |
bool | isElement () const |
bool | isEntity () const |
bool | isEntityReference () const |
bool | isNotation () const |
bool | isNull () const |
bool | isProcessingInstruction () const |
bool | isSupported (const QString & feature , const QString & version ) const |
bool | isText () const |
QDomNode | lastChild () const |
QDomElement | lastChildElement (const QString & tagName = QString()) const |
int | lineNumber () const |
QString | localName () const |
QDomNode | namedItem (const QString & name ) const |
QString | namespaceURI () const |
QDomNode | nextSibling () const |
QDomElement | nextSiblingElement (const QString & tagName = QString()) const |
QString | nodeName () const |
QDomNode::NodeType | nodeType () const |
QString | nodeValue () const |
void | normalize () |
QDomDocument | ownerDocument () const |
QDomNode | parentNode () const |
QString | prefix () const |
QDomNode | previousSibling () const |
QDomElement | previousSiblingElement (const QString & tagName = QString()) const |
QDomNode | removeChild (const QDomNode & oldChild ) |
QDomNode | replaceChild (const QDomNode & newChild , const QDomNode & oldChild ) |
void | save (QTextStream & stream , int indent , QDomNode::EncodingPolicy encodingPolicy = QDomNode::EncodingFromDocument) const |
void | setNodeValue (const QString & v ) |
void | setPrefix (const QString & pre ) |
QDomAttr | toAttr () const |
QDomCDATASection | toCDATASection () const |
QDomCharacterData | toCharacterData () const |
QDomComment | toComment () const |
QDomDocument | toDocument () const |
QDomDocumentFragment | toDocumentFragment () const |
QDomDocumentType | toDocumentType () const |
QDomElement | toElement () const |
QDomEntity | toEntity () const |
QDomEntityReference | toEntityReference () const |
QDomNotation | toNotation () const |
QDomProcessingInstruction | toProcessingInstruction () const |
QDomText | toText () const |
bool | operator!= (const QDomNode & n ) const |
QDomNode & | operator= (const QDomNode & n ) |
bool | operator== (const QDomNode & n ) const |
QDomNodePrivate * | impl |
QTextStream & | operator<< (QTextStream & str , const QDomNode & node ) |
The QDomNode 类是 DOM (文档对象模型) 树中所有节点的基类。
DOM 中的很多函数返回 QDomNode .
可以找出节点的类型使用 isAttr (), isCDATASection (), isDocumentFragment (), isDocument (), isDocumentType (), isElement (), isEntityReference (), isText (), isEntity (), isNotation (), isProcessingInstruction (), isCharacterData () 和 isComment ().
A QDomNode 可以被转换成其子类之一使用 toAttr (), toCDATASection (), toDocumentFragment (), toDocument (), toDocumentType (), toElement (), toEntityReference (), toText (), toEntity (), toNotation (), toProcessingInstruction (), toCharacterData () 或 toComment ()。可以将节点转换为 null 节点采用 clear ().
副本 QDomNode 类使用明确共享,共享它们的数据。这意味着修改一节点将改变所有副本。这尤其有用,当组合函数返回 QDomNode ,如 firstChild ()。可以制作节点的独立 (深) 拷贝采用 cloneNode ().
A QDomNode 可以为 null,非常像 null 指针。创建 null 节点副本会产生另一 null 节点。修改 null 节点是不可能的,但将另一可能非 null 节点赋值给它是可能的。在这种情况下,null 节点副本将仍然为 null。可以校验是否 QDomNode 为 null 通过调用 isNull ()。空构造函数 QDomNode (或任何派生类) 创建 null 节点。
插入节点采用 insertBefore (), insertAfter () 或 appendChild ()。可以采用另一节点替换某个节点使用 replaceChild () 和移除节点采用 removeChild ().
要遍历节点使用 firstChild () 以获取节点的第一子级 (若有的话),和 nextSibling () 去遍历。 QDomNode 还提供 lastChild (), previousSibling () 和 parentNode ()。要查找具有特定节点名称的第一子级节点使用 namedItem ().
要找出节点是否拥有子级使用 hasChildNodes () 和要获取节点的所有子级的列表使用 childNodes ().
节点名称和值 (其含义因类型而异) 的返回通过 nodeName () 和 nodeValue () 分别。节点类型的返回通过 nodeType ()。可以设置节点的值采用 setNodeValue ().
节点所属文档的返回通过 ownerDocument ().
相邻 QDomText 节点可以合并成单个节点采用 normalize ().
QDomElement 可以检索节点拥有的属性采用 属性 ().
QDomElement and QDomAttr 节点可以拥有可以检索的名称空间采用 namespaceURI ()。它们的本地名称的检索采用 localName (),和它们的前缀采用 prefix ()。可以设置前缀采用 setPrefix ().
可以将节点的 XML 表示写入文本流采用 save ().
以下范例查找 XML 文档第一元素并打印其直接子级所有元素的名称。
QDomDocument d; d.setContent(someXML); QDomNode n = d.firstChild(); while (!n.isNull()) { if (n.isElement()) { QDomElement e = n.toElement(); cout << "Element name: " << e.tagName() << endl; break; } n = n.nextSibling(); }
有关文档对象模型的进一步信息,见 级别 1 and 级别 2 核心 。有关 DOM 实现的更一般介绍,见 QDomDocument 文档编制。
此枚举指定如何 QDomNode::save () 确定要使用什么编码当序列化时。
常量 | 值 | 描述 |
---|---|---|
QDomNode::EncodingFromDocument
|
1
|
编码抓取自文档。 |
QDomNode::EncodingFromTextStream
|
2
|
编码抓取自 QTextStream . |
该枚举在 Qt 4.3 引入或被修改。
另请参阅 QDomNode::save ().
此枚举定义节点的类型:
常量 | 值 | 描述 |
---|---|---|
QDomNode::ElementNode
|
1
|
|
QDomNode::AttributeNode
|
2
|
|
QDomNode::TextNode
|
3
|
|
QDomNode::CDATASectionNode
|
4
|
|
QDomNode::EntityReferenceNode
|
5
|
|
QDomNode::EntityNode
|
6
|
|
QDomNode::ProcessingInstructionNode
|
7
|
|
QDomNode::CommentNode
|
8
|
|
QDomNode::DocumentNode
|
9
|
|
QDomNode::DocumentTypeNode
|
10
|
|
QDomNode::DocumentFragmentNode
|
11
|
|
QDomNode::NotationNode
|
12
|
|
QDomNode::BaseNode
|
21
|
A QDomNode 对象,即不是 QDomNode 子类。 |
QDomNode::CharacterDataNode
|
22
|
构造 null 节点。
构造副本为 n .
拷贝数据是共享的 (浅拷贝):修改一节点也会改变另一节点。若想要做深拷贝,使用 cloneNode ().
销毁对象并释放其资源。
追加 newChild 作为节点的最后子级。
若 newChild 是另一节点的子级,它会重设父级到此节点。若 newChild 是此节点的子级,那么它在子级列表中的位置会改变。
若 newChild 是 QDomDocumentFragment ,那么片段的子级将从片段中移除并追加。
若 newChild 是 QDomElement 和此节点是 QDomDocument ,已经拥有的元素节点将作为子级, newChild 不添加作为子级并返回 null 节点。
返回新的引用为 newChild 当成功时或 null 节点 当故障时。
在 null 节点 (例如:采用默认构造函数创建) 调用此函数什么都不做并返回 null 节点 .
DOM 规范禁止插入属性节点,但由于历史原因,无论如何 QDom 接受它们。
另请参阅 insertBefore (), insertAfter (), replaceChild (),和 removeChild ().
返回所有属性的命名节点映射。才提供属性对于 QDomElement 。
改变映射中的属性也会改变其属性对于此 QDomNode .
返回所有直接子级节点的列表。
大多数情况下,会调用此函数在 QDomElement 对象。
例如,若 XML 文档看起来像这样:
<body> <h1>Heading</h1> <p>Hello <b>you</b></p> </body>
那么 body 元素的子级节点列表将包含由 <h1> 和 <p> 标签创建的节点。
列表中的节点不是副本;因此改变列表中的节点也会改变此节点的子级。
另请参阅 firstChild () 和 lastChild ().
将节点转换为 null 节点;若它之前不是 null 节点,删除其类型和内容。
另请参阅 isNull ().
创建深 (非浅) 副本为 QDomNode .
若 deep 为 true,那么会递归完成克隆,意味着所有节点的子级也被深拷贝。若 deep 为 false 仅节点本身被拷贝且副本没有子级节点。
对于创建的节点通过 QDomDocument::setContent (),此函数返回经剖析 XML 文档节点的列数。否则,返回 -1。
该函数在 Qt 4.1 引入。
另请参阅 lineNumber () 和 QDomDocument::setContent ().
返回节点的第一子级。若没有子级节点, null 节点 被返回。改变返回节点也会改变文档树节点。
另请参阅 lastChild () 和 childNodes ().
返回的第一子级元素具有标签名称 tagName 若 tagName 非空; 否则返回第一子级元素。返回 null 元素若不存在这样的子级。
另请参阅 lastChildElement (), previousSiblingElement (),和 nextSiblingElement ().
返回
true
若节点拥有属性;否则返回
false
.
另请参阅 属性 ().
返回
true
若节点拥有一个或多个子级;否则返回
false
.
插入节点 newChild 后于子级节点 refChild . refChild 必须是此节点的直接子级。若 refChild is null then newChild 被追加作为此节点的最后子级。
若 newChild 是另一节点的子级,它会重设父级到此节点。若 newChild 是此节点的子级,那么它在子级列表中的位置会改变。
若 newChild 是 QDomDocumentFragment ,那么片段的子级将从片段被移除并插入后于 refChild .
返回新的引用为 newChild 当成功时或 null 节点 当故障时。
DOM 规范禁止插入属性节点,但由于历史原因 QDom 仍然接受它们。
另请参阅 insertBefore (), replaceChild (), removeChild (),和 appendChild ().
插入节点 newChild 前于子级节点 refChild . refChild 必须是此节点的直接子级。若 refChild is null then newChild 被插入作为节点的第一子级。
若 newChild 是另一节点的子级,它会重设父级到此节点。若 newChild 是此节点的子级,那么它在子级列表中的位置会改变。
若 newChild 是 QDomDocumentFragment ,那么片段的子级将从片段被移除并插入前于 refChild .
返回新的引用为 newChild 当成功时或 null 节点 当故障时。
DOM 规范禁止插入属性节点,但由于历史原因 QDom 仍然接受它们。
另请参阅 insertAfter (), replaceChild (), removeChild (),和 appendChild ().
返回
true
若节点是属性;否则返回
false
.
若此函数返回
true
,它并未暗示此对象是 QDomAttribute;可以采用 toAttribute() 获取 QDomAttribute。
另请参阅 toAttr ().
返回
true
若节点是 CDATA 区间;否则返回 false。
若此函数返回
true
,它并未暗示此对象是
QDomCDATASection
;可以获取
QDomCDATASection
with
toCDATASection
().
另请参阅 toCDATASection ().
返回
true
若节点是字符数据节点;否则返回
false
.
若此函数返回
true
,它并未暗示此对象是
QDomCharacterData
;可以获取
QDomCharacterData
with
toCharacterData
().
另请参阅 toCharacterData ().
返回
true
若节点是注释;否则返回
false
.
若此函数返回
true
,它并未暗示此对象是
QDomComment
;可以获取
QDomComment
with
toComment
().
另请参阅 toComment ().
返回
true
若节点是文档;否则返回
false
.
若此函数返回
true
,它并未暗示此对象是
QDomDocument
;可以获取
QDomDocument
with
toDocument
().
另请参阅 toDocument ().
返回
true
若节点是文档片段;否则返回 false。
若此函数返回
true
,它并未暗示此对象是
QDomDocumentFragment
;可以获取
QDomDocumentFragment
with
toDocumentFragment
().
另请参阅 toDocumentFragment ().
返回
true
若节点是文档类型;否则返回 false。
若此函数返回
true
,它并未暗示此对象是
QDomDocumentType
;可以获取
QDomDocumentType
with
toDocumentType
().
另请参阅 toDocumentType ().
返回
true
若节点是元素;否则返回
false
.
若此函数返回
true
,它并未暗示此对象是
QDomElement
;可以获取
QDomElement
with
toElement
().
另请参阅 toElement ().
返回
true
若节点是实体;否则返回
false
.
若此函数返回
true
,它并未暗示此对象是
QDomEntity
;可以获取
QDomEntity
with
toEntity
().
另请参阅 toEntity ().
返回
true
若节点是实体引用;否则返回 false。
若此函数返回
true
,它并未暗示此对象是
QDomEntityReference
;可以获取
QDomEntityReference
with
toEntityReference
().
另请参阅 toEntityReference ().
返回
true
若节点是表示法;否则返回
false
.
若此函数返回
true
,它并未暗示此对象是
QDomNotation
;可以获取
QDomNotation
with
toNotation
().
另请参阅 toNotation ().
返回
true
若此节点为 null (即:若它没有类型或内容);否则返回
false
.
返回
true
若节点是处理指令;否则返回
false
.
若此函数返回
true
,它并未暗示此对象是
QDomProcessingInstruction
;可以获取 QProcessingInstruction 采用
toProcessingInstruction
().
另请参阅 toProcessingInstruction ().
返回
true
若 DOM (文档对象模型) 实现实现特征
feature
且此特征由此节点支持在版本
version
;否则返回
false
.
另请参阅 QDomImplementation::hasFeature ().
返回
true
若节点是文本节点;否则返回
false
.
若此函数返回
true
,它并未暗示此对象是
QDomText
;可以获取
QDomText
with
toText
().
另请参阅 toText ().
返回节点的最后子级。若没有子级节点, null 节点 被返回。改变返回节点也会改变文档树节点。
另请参阅 firstChild () 和 childNodes ().
返回的最后子级元素具有标签名称 tagName 若 tagName 非空;否则返回最后子级元素。返回 null 元素,若不存在这种子级。
另请参阅 firstChildElement (), previousSiblingElement (),和 nextSiblingElement ().
对于创建的节点通过 QDomDocument::setContent (),此函数返回剖析节点的 XML 文档行号。否则,返回 -1。
该函数在 Qt 4.1 引入。
另请参阅 columnNumber () 和 QDomDocument::setContent ().
若节点使用名称空间,此函数返回节点的本地名称;否则它返回空字符串。
仅节点为类型 ElementNode or AttributeNode 可以拥有名称空间。名称空间必须在创建时指定;之后添加名称空间不可能。
另请参阅 prefix (), namespaceURI (), QDomDocument::createElementNS (),和 QDomDocument::createAttributeNS ().
返回第一直接子级节点对于其 nodeName () 等于 name .
若不存在这种直接子级, null 节点 被返回。
另请参阅 nodeName ().
返回此节点的名称空间 URI 或空字符串,若节点没有名称空间 URI。
仅节点为类型 ElementNode or AttributeNode 可以拥有名称空间。名称空间 URI 必须在创建时指定且以后不能更改。
另请参阅 prefix (), localName (), QDomDocument::createElementNS (),和 QDomDocument::createAttributeNS ().
返回文档树中的下一同级。改变返回节点还会改变文档树中的节点。
若拥有的 XML 像这样:
<h1>Heading</h1> <p>The text...</p> <h2>Next heading</h2>
和此 QDomNode 表示 <p> 标签,nextSibling() 将返回 <h2> 标签表示节点。
另请参阅 previousSibling ().
返回的下一同级元素具有标签名称 tagName if tagName 非空;否则返回任何下一同级元素。返回 null 元素,若不存在这种同级。
另请参阅 firstChildElement (), previousSiblingElement (),和 lastChildElement ().
返回节点的名称。
名称的含义从属子类:
名称 | 含义 |
---|---|
QDomAttr | 属性名称 |
QDomCDATASection | 字符串 "#cdata-section" |
QDomComment | 字符串 "#comment" |
QDomDocument | 字符串 "#document" |
QDomDocumentFragment | 字符串 "#document-fragment" |
QDomDocumentType | 文件类型的名称 |
QDomElement | 标签名称 |
QDomEntity | 实体名称 |
QDomEntityReference | 引用实体的名称 |
QDomNotation | 表示法名称 |
QDomProcessingInstruction | 处理指令的目标 |
QDomText | 字符串 "#text" |
注意: 此函数不考虑名称空间的存在,当处理元素和属性节点的名称时。因此,返回名称可以包含可能存在的任何名称空间前缀。要获得元素或属性的节点名称,使用 localName ();要获得名称空间前缀,使用 namespaceURI ().
另请参阅 nodeValue ().
返回节点的类型。
另请参阅 toAttr (), toCDATASection (), toDocumentFragment (), toDocument (), toDocumentType (), toElement (), toEntityReference (), toText (), toEntity (), toNotation (), toProcessingInstruction (), toCharacterData (),和 toComment ().
返回节点的值。
值的含义从属子类:
名称 | 含义 |
---|---|
QDomAttr | 属性值 |
QDomCDATASection | CDATA 区间的内容 |
QDomComment | 注释 |
QDomProcessingInstruction | 处理指令的数据 |
QDomText | 文本 |
所有其它子类没有节点值,且会返回空字符串。
另请参阅 setNodeValue () 和 nodeName ().
调用元素的 normalize() 会将其所有子级转换成标准形式。这意味着相邻 QDomText 对象将被合并成单文本对象 ( QDomCDATASection 节点不会被合并)。
返回此节点所属的文档。
返回父级节点。若此节点没有父级,返回 null 节点 (即:节点的
isNull
() 返回
true
).
返回节点名称空间前缀,或空字符串若节点没有名称空间前缀。
仅节点为类型 ElementNode or AttributeNode 可以拥有名称空间。必须在创建时指定名称空间前缀。若节点是采用名称空间前缀创建的,可以稍后改变它采用 setPrefix ().
如果创建元素或属性采用 QDomDocument::createElement () 或 QDomDocument::createAttribute (),前缀将是空字符串。若使用 QDomDocument::createElementNS () 或 QDomDocument::createAttributeNS () 代替,前缀不会是空字符串;但它可能是空字符串,若名称尚未拥有前缀。
另请参阅 setPrefix (), localName (), namespaceURI (), QDomDocument::createElementNS (),和 QDomDocument::createAttributeNS ().
返回文档树的上一同级。改变返回节点也会改变文档树节点。
例如,若拥有的 XML 像这样:
<h1>Heading</h1> <p>The text...</p> <h2>Next heading</h2>
和此 QDomNode 表示 <p> 标签,previousSibling() 将返回 <h1> 标签表示节点。
另请参阅 nextSibling ().
返回的上一同级元素具有标签名称 tagName if tagName 非空;否则返回任何先前同级元素。返回 null 元素若不存在这样的同级。
另请参阅 firstChildElement (), nextSiblingElement (),和 lastChildElement ().
移除 oldChild 从子级列表。 oldChild 必须是此节点的直接子级。
返回新的引用为 oldChild 当成功时或 null 节点 当故障时。
另请参阅 insertBefore (), insertAfter (), replaceChild (),和 appendChild ().
替换 oldChild with newChild . oldChild 必须是此节点的直接子级。
若 newChild 是另一节点的子级,它会重设父级到此节点。若 newChild 是此节点的子级,那么它在子级列表中的位置会改变。
若 newChild 是 QDomDocumentFragment ,那么 oldChild 被片段的所有子级所替换。
返回新的引用为 oldChild 当成功时或 null 节点 当故障时。
另请参阅 insertBefore (), insertAfter (), removeChild (),和 appendChild ().
将节点及其所有子级的 XML 表示写入流 stream 。此函数使用 indent 作为节点的缩进空格数。
若文档包含无效 XML 字符或不能以给定编码编码字符,结果和行为未定义。
若 encodingPolicy is QDomNode::EncodingFromDocument 和此节点是文档节点,编码的文本流 stream 的编码是通过将名称 xml 的处理指令视为 XML 声明来设置的 (若存在一个的话),否则默认为 UTF-8。XML 声明不是处理指令,但由于历史原因而存在此行为。若此节点不是文档节点,使用文本流编码。
若 encodingPolicy is EncodingFromTextStream 和此节点是文档节点,此函数行为如 save( QTextStream &str, int indent) 除了指定编码在文本流 stream 被使用。
若文档包含无效 XML 字符或不能以给定编码编码字符,结果和行为未定义。
该函数在 Qt 4.2 引入。
将节点值设为 v .
另请参阅 nodeValue ().
若节点拥有名称空间前缀,此函数将节点名称空间前缀改为 pre 。否则此函数什么都不做。
仅节点为类型 ElementNode or AttributeNode 可以拥有名称空间。必须在创建时指定名称空间前缀;之后添加名称空间前缀是不可能的。
另请参阅 prefix (), localName (), namespaceURI (), QDomDocument::createElementNS (),和 QDomDocument::createAttributeNS ().
转换 QDomNode 成 QDomAttr 。若节点不是属性,返回对象将是 null .
另请参阅 isAttr ().
转换 QDomNode 成 QDomCDATASection 。若节点不是 CDATA 区间,返回对象将是 null .
另请参阅 isCDATASection ().
转换 QDomNode 成 QDomCharacterData 。若节点不是字符数据,返回对象将是 null .
另请参阅 isCharacterData ().
转换 QDomNode 成 QDomComment 。若节点不是注释,返回对象将是 null .
另请参阅 isComment ().
转换 QDomNode 成 QDomDocument 。若节点不是文档,返回对象将是 null .
另请参阅 isDocument ().
转换 QDomNode 成 QDomDocumentFragment 。若节点不是文档片段,返回对象将是 null .
另请参阅 isDocumentFragment ().
转换 QDomNode 成 QDomDocumentType 。若节点不是文档类型,返回对象将是 null .
另请参阅 isDocumentType ().
转换 QDomNode 成 QDomElement 。若节点不是元素,返回对象将是 null .
另请参阅 isElement ().
转换 QDomNode 成 QDomEntity 。若节点不是实体,返回对象将是 null .
另请参阅 isEntity ().
转换 QDomNode 成 QDomEntityReference 。若节点不是实体引用,返回对象将是 null .
另请参阅 isEntityReference ().
转换 QDomNode 成 QDomNotation 。若节点不是表示法,返回对象将是 null .
另请参阅 isNotation ().
转换 QDomNode 成 QDomProcessingInstruction 。若节点不是处理指令,返回对象将是 null .
另请参阅 isProcessingInstruction ().
转换 QDomNode 成 QDomText 。若节点不是文本,返回对象将是 null .
另请参阅 isText ().
返回
true
if
n
和此 DOM 节点不相等;否则返回
false
.
赋值副本为 n 到此 DOM (文档对象模型) 节点。
拷贝数据是共享的 (浅拷贝):修改一节点也会改变另一节点。若想要做深拷贝,使用 cloneNode ().
返回
true
if
n
和此 DOM 节点相等;否则返回
false
.
任何实例化的 QDomNode 充当底层数据结构的引用在 QDomDocument 。相等测试校验 2 引用是否指向同一底层节点。例如:
QDomDocument document; QDomElement element1 = document.documentElement(); QDomElement element2 = element1;
2 节点 (
QDomElement
是
QDomNode
子类) 引用文档根元素,且
element1 == element2
会返回 true。另一方面:
QDomElement element3 = document.createElement("MyElement"); QDomElement element4 = document.createElement("MyElement");
即使 2 节点是携带相同名称的空元素,
element3 == element4
会返回 false 因为它们引用底层数据结构中的 2 不同节点。
写入 XML 表示在节点 node 及其所有子级到流 str .