private QilNode CompileCopyOf(XslNode node)
{
QilNode selectExpr = CompileXPathExpression(node.Select);
if (selectExpr.XmlType.IsNode)
{
if ((selectExpr.XmlType.NodeKinds & InvalidatingNodes) != XmlNodeKindFlags.None)
{
_outputScope.InvalidateAllPrefixes();
}
if (selectExpr.XmlType.IsNotRtf && (selectExpr.XmlType.NodeKinds & XmlNodeKindFlags.Document) == XmlNodeKindFlags.None)
{
// Expression returns non-document nodes only
return selectExpr;
}
// May be an Rtf or may return Document nodes, so use XsltCopyOf operator
if (selectExpr.XmlType.IsSingleton)
{
return _f.XsltCopyOf(selectExpr);
}
else
{
QilIterator it;
return _f.Loop(it = _f.For(selectExpr), _f.XsltCopyOf(it));
}
}
else if (selectExpr.XmlType.IsAtomicValue)
{
// Expression returns non-nodes only
// When the result is neither a node-set nor a result tree fragment, the result is converted
// to a string and then inserted into the result tree, as with xsl:value-of.
return _f.TextCtor(_f.ConvertToString(selectExpr));
}
else
{
// Static classifying is not possible
QilIterator it;
_outputScope.InvalidateAllPrefixes();
return _f.Loop(
it = _f.For(selectExpr),
_f.Conditional(_f.IsType(it, T.Node),
_f.XsltCopyOf(_f.TypeAssert(it, T.Node)),
_f.TextCtor(_f.XsltConvert(it, T.StringX))
)
);
}
}